运维开发网

Feign传输的日期类型参数中存在错误

运维开发网 https://www.qedev.com 2022-10-12 14:45 出处:网络
这篇文章主要介绍了SpringCloud?Feign?传输Date类型参数存在误差的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教 <p class="maodian"></p>Feign传输

这篇文章主要介绍了SpringCloud?Feign?传输Date类型参数存在误差的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教 <p class="maodian"></p>Feign传输Date类型参数存在误差<p>在最近的项目开发过程中,前端传递的时间(日期类型)在A模块中是正确的,然后A模块调用B模块将时间(日期类型)作为参数传递,然后B模块接收的时间出现错误。天数会增加一天,小时会减少10小时,应该是SpringCloud Feign组件导致的问题。</p><p>我这里的解决方法是在模块A调用之前把时间(日期类型)改成字符串类型,然后在模块B收到模块A的参数之后把时间从字符串类型改成日期类型。</p><p class="maodian"></p>时间转换代码如下/*** 日期格式化为字符串** @param source* @return java.lang.String* @author zxzhang* @date 2020/2/9*/public Date string2date(String source) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.parse(source);}/*** 字符串解析为日期** @param source* @return java.lang.String* @author zxzhang* @date 2020/2/9*/public String date2String(Date source) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(source);}<p>完美解决了传递给Feign的日期类型参数的错误问题。</p><p class="maodian"></p>Feign传输date类型参数,时间差14个小时<p class="maodian"></p>Java Date类型的时差问题<p>看看下面的代码。</p>public static void main(String[] args) throws Exception { Date date1 = new Date(); System.out.println("date1: " + date1.toString()); Date date2 = new Date(date1.toString()); System.out.println("date2: " + date2.toString());}<p>执行结果如下</p><p>日期1:2019年7月22日星期一08时47分19秒<br>日期2:2019年7月22日星期一22时47分19秒</p><p>现在的时间是2019年7月22日8点48分。CST是中国标准时间的缩写,是中国的一个时区,但是可以看到date2的输入比实际时间多了14个小时。</p><p>实际上,CTS代表四个时区(中部标准时间(美国)UT-6: 00,中部标准时间(澳大利亚)UT+9: 30,中国标准时间UT+8:00,古巴标准时间UT-4:00),它还代表美国、澳大利亚、中国和古巴的标准时间。</p><p>原因</p>new Date(date1.toString())<p>这个方法调用Date.parse(String)方法,它传递的参数是Mon Jul 22 08:47:19 CST 2019。对这种方法有一个评论。</p>* lt;ligt;Any word that matches lt;ttgt;EST, CST, MSTlt;/ttgt;, or lt;ttgt;PSTlt;/ttgt;,* ignoring case, is recognized as referring to the time zone in* North America that is five, six, seven, or eight hours west of* Greenwich, respectively. Any word that matches lt;ttgt;EDT, CDT,* MDTlt;/ttgt;, or lt;ttgt;PDTlt;/ttgt;, ignoring case, is recognized as* referring to the same time zone, respectively, during daylight* saving time.lt;/ulgt;lt;pgt;<p>可以看到,CST会被视为美国中部的中部标准时间,即JVM认为你的到来时间是美国中部时间,当date2调用toString方法时,会检测到系统的时区是中国,会自动加上14小时(东8区和西6区的时差),就变成Mon Jul 22 22:47:19 CST 2019。</p><p class="maodian"></p><p class="maodian"></p>解决方法<p>其实如果自己写代码的话这个问题是很难出现的,因为所有的Java书都不是这么教的,大部分都是用SimpleDateFormat来转换日期和字符串。毕竟,新的Date(date1.toString())方法已经被标记为过时。</p><p class="maodian"></p>Feign客户端的问题<p>当Feign client通信时,它将调用Date的toString方法,并将其更改为String类型。当服务器接受它时,它使用新的日期(字符串)方法。这里会发生上述问题,造成14小时时差。</p>解决方法<p>在客户机上添加代码,指定Feign将日期参数转换为字符串参数的格式:</p>import lombok.extern.slf4j.Slf4j;import org.springframework.cloud.openfeign.FeignFormatterRegistrar;import org.springframework.core.convert.converter.Converter;import org.springframework.format.FormatterRegistry;import org.springframework.stereotype.Component;import java.text.SimpleDateFormat;import java.util.Date;@Slf4j@Componentpublic class FeignDateFormatRegister implements FeignFormatterRegistrar { @Override public void registerFormatters(FormatterRegistry registry) { registry.addConverter(Date.class, String.class, new Date2StringConverter()); } private class Date2StringConverter implements Converterlt;Date, Stringgt; { @Override public String convert(Date source) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(source); } }}<p>在服务器端添加代码,以字符串和日期的形式指定SpringContext使用的转换器,并让转换器知道我们在客户端配置的参数格式:</p>import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.core.convert.converter.Converter;import org.springframework.core.convert.support.GenericConversionService;import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;import javax.annotation.PostConstruct;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;@Slf4j@Configurationpublic class FeignConfiguration { @Autowired private RequestMappingHandlerAdapter handlerAdapter; /** * 增加字符串转日期的功能 */ @PostConstruct public void initEditableValidation() { ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) handlerAdapter.getWebBindingInitializer(); if (initializer.getConversionService() != null) { GenericConversionService genericConversionService = (GenericConversionService) initializer.getConversionService(); genericConversionService.addConverter(String.class, Date.class, new String2DateConverter()); } } class String2DateConverter implements Converterlt;String, Dategt; { @Override public Date convert(String source) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { return simpleDateFormat.parse(source); } catch (ParseException e) { log.error("", e); } return null; } }}<p>注意,以上两个配置类需要配置自己的包扫描,

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号