文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何解决SpringCloud Feign传输Date类型参数存在误差的问题

2023-06-29 11:58

关注

这篇文章将为大家详细讲解有关如何解决SpringCloud Feign传输Date类型参数存在误差的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

Feign传输Date类型参数存在误差

最近在项目开发过程中,前端传递过来的时间(Date类型)在A模块是正确的,然后A模块调用B模块将时间(Date类型)作为参数传过去,然后B模块接收到的时间有误差,天数会多一天,小时少10小时,这应该是SpringCloud Feign组件造成的问题

我这里的解决办法是在A模块调用之前先将时间(Date类型)转为String类型,B模块接收到A模块的参数后将时间由String类型再转为Date类型就可以了

时间转换代码如下

public Date string2date(String source) throws ParseException {    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    return sdf.parse(source);} public String date2String(Date source) {    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    return sdf.format(source);}

到此 Feign 传输Date类型参数存在误差的问题完美解决。

Feign传输date类型参数,时间差14个小时

Java Date类型的时差问题

请看下边这段代码

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());}

执行结果如下

date1: Mon Jul 22 08:47:19 CST 2019
date2: Mon Jul 22 22:47:19 CST 2019

当前时间是2019年7月22日8点48分,CST是中国的时区China Standard Time的简称,但是可以看到date2的输入比实际时间多了14个小时。

CTS代表的时区其实有四个(Central Standard Time (USA) UT-6:00、Central Standard Time (Australia) UT+9:30、China Standard Time UT+8:00、Cuba Standard Time UT-4:00),同时表示美国,澳大利亚,中国,古巴四个国家的标准时间。

原因

new Date(date1.toString())

这个方法会调用Date.parse(String)方法,它传的参数是Mon Jul 22 08:47:19 CST 2019,这个方法上有一段注释

* <li>Any word that matches <tt>EST, CST, MST</tt>, or <tt>PST</tt>,*     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 <tt>EDT, CDT,*     MDT</tt>, or <tt>PDT</tt>, ignoring case, is recognized as*     referring to the same time zone, respectively, during daylight*     saving time.</ul><p>

可以看到CST会被当作美国中部的时区Central Standard Time,即JVM认为你传入的时间是美国中部的时间,而当date2调用toString方法的时候,它会检测到系统的时区是中国,就会自动加14个小时(东八区与西六区的时差),就变成了Mon Jul 22 22:47:19 CST 2019

解决方法

这个问题其实如果自己写代码的话很难出现,因为所有的Java书籍都不会这么教,大多数都是通过SimpleDateFormat,进行Date和String的转换,毕竟new Date(date1.toString())这个方法已经标注为废弃了

Feign客户端的问题

Feign客户端在进行通信时,会调用Date的toString方法转为String类型,服务端在接受的时候,使用的就是new Date(String)这个方法,这里就会发生前边介绍的问题,产生14个小时的时差

解决方法

在客户端添加代码,规定Feign在将Date参数转化成String参数的格式:

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 Converter<Date, String> {        @Override        public String convert(Date source) {            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");            return sdf.format(source);        }     }}

在服务端添加代码,规定SpringContext在String和Date时的用的转化器,让转化器知道我们在客户端配置的参数格式:

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 Converter<String, Date> {        @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;        }    }}

注意以上两个配置类需要自己配置包扫描之类的把它们加到Spring环境中

关于“如何解决SpringCloud Feign传输Date类型参数存在误差的问题”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯