首页 > 作文

Springcloud feign传日期类型参数报错的解决方案

更新时间:2023-04-06 03:46:42 阅读: 评论:0

feign传日期类型参数报错

date类型参数报错

在spring cloud feign接口中传递date类型参数时报错,报错信息。

场景:

客户端传递一个new date()的参数,服务端接受的参数和客户端有时间差。

客户端打印格式化的new date():

2018-05-11 10:23:36

而服务端接收到的参数是:

2018-05-12 00:23:36

我们从feign启动的源码可以看出,feign在encode和decode时会用springencoder类来实现:

  @bean  @conditionalonmissingbean  public decoder feigndecoder() {    return new responentitydecoder(new springdecoder(this.messageconverters));  }  @bean  @conditionalonmissingbean  public encoder feignencoder() {    return new springencoder(this.messageconverters);  }

而springencoder的httpmessageconverters使用的是jackson默认模板,该模板来自基类webmvcconfigurationsupport.java:

  protected final list<httpmessageconverter<?>> getmessageconverters() {    if (this.messageconverters == null) {      thi袁隆平 的主要事迹简介s.messageconverters = new arraylist<httpmessageconverter<?>>();      configuremessageconverters(this.messageconverters);      if (this.messageconverters.impty()) {        adddefaulthttpmessageconverters(this.messageconverters);      }      extendmessageconverters(this.messageconverters);    }    return this.messageconverters;  }

而webmvcconfigurationsupport.java最终使用的是默认的objectmapper生成的mappingjackson2httpmessageconverter。

至此可以看出该问题的产生并不是feign的问题,而是feign实现中使用的spring mvc中的jackson转换参数问题,默认的timezone并不是东八区,而是utc。

  /**  * override the default {@link timezone} to u for formatting.  * default value ud is utc (not local timezone).  * @since 4.1.5  */  public jackson2objectmapperbuilder timezone(timezone timezone) {    thi签约仪式活动方案s.timezone = timezone;    return this;  }

这个问题,在spring mvc中可以在接口或者字段上添加注解来解决,但在feign中使用get请求的接口添加注解是不行的。debug发现,spring mvc在处理date的时候,调用了sun.reflect.constructoraccessor#newinstance(object[] var1),时间会加14个小时。具体实现没看到源码,后续再研究。需要说明的是,加jsonformat注解对于feign接口没生效,但spring mvc是可以的。

ok,回到正题。要解决这个问题,最好的办法是自定义objectmapper。即使是加了注解可以解决问题,也依然推荐使用自定义objectmapper,因为大量的接口每个都添加注解太繁琐了。

  @bean  @primary  public objectmapper objectmapper() {    return jackson2objectmapperbuilder.json()        .rializationinclusion(jsoninclude.include.non_null)        .featurestodisable(rializationfeature.write_dates_as_timestamps)        .timezone(timezone.gettimezone("asia/shanghai"))        .build();  }

这样注解进去的objectmapper就带了时区。

localdate类型报错

报错详情:

稽查报告

failed to read http message短篇作文: org.springframework.http.converter.httpmessagenotreadableexception: json par error: can not construct instance of java.time.localdate: no suitable constructor found, can not derialize from object value (missing default constructor or creator, or perhaps need to add/enable type information?); nested exception is com.fasterxml.jackson.databind.jsonmappingexception: can not construct instance of java.time.localdate: no suitable constructor found, can not derialize from object value (missing default constructor or creator, or perhaps need to add/enable type information?)
at [source: java.io.pushbackinputstream@3ce2b1e2; line: 1, column: 44] (through reference chain: com.chunrun.ur.param.urparams[“localdate”])

这是因为localdate没有提供默认的构造器,而jackson还不支持java8的特征。这时候只需要加上依赖,objectmapper加一行代码即可:

  <dependency>   <groupid>com.fasterxml.jackson.datatype</groupid>   <artifactid>jackson-datatype-jsr310</artifactid>   <ve全国计算机二级成绩查询入口rsion>2.4.0</version>  </dependency>
  @bean  @primary  public objectmapper objectmapper() {    return jackson2objectmapperbuilder.json()        .rializationinclusion(jsoninclude.include.non_null)        .featurestodisable(rializationfeature.write_dates_as_timestamps)        .timezone(timezone.gettimezone("asia/shanghai"))        .modules(new jsr310module())        .build();  }

以上配置调用方也需要。

feign传参问题及传输date类型参数时差的坑

feign的调用如下:

list<leftatcountofdaysresp> getleftatcountofdays(            @requestparam("configtype") integer configtype,            @requestparam("courid") long courid,            @requestparam("startdatefrom") date startdatefrom,            @requestparam("startdateto") date startdateto,            @requestparam("level") integer level); 

我们采用了两个date类型的参数传参,结果:

我们传入的时间为:

但服务端接受到的时间为:

天啊撸,竟然出现了我们并不熟悉的14h时差,并不是我们熟悉的8个小时。feign真是天坑啊。这是springcloud feign传date类型参数的时差导致的。

备注:使用date类型传参,如果是body里面用对象传,是不会出现时差问题的。

下面说说两种解决方案

当发送时间类型时,直接用string发送(推荐)feign客户端实现feignformatterregistrar接口自定义dateformatregister
@component    public class dateformatregister implements feignformatterregistrar{        public dateformatregister(){        }        @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);            }        }    } 

服务端实现:

@configuration    public class webconfigbeans {        @autowired        private requestmappinghandleradapter handleradapter;        /**        * 增加字符串转日期的功能        */        @postconstruct        public void initeditablevalidation() {            configurablewebbindinginitializer initializer = (configurablewebbindinginitializer) handleradapter                        .getwebbindinginitializer();            if (initializer.getconversionrvice() != null) {                genericconversionrvice genericconversionrvice = (genericconversionrvice) initializer                            .getconversionrvice();                genericconversionrvice.addconverter(string.class, date.class, new string2dateconverter());            }        }    } 

第二种比较麻烦,但是一劳永逸,代码的优雅性比第一种好。但个人而言,还是推荐使用第一种。

feign传参时候使用@datetimeformat注解的坑

@notnull    @myfuture    @datetimeformat(pattern = "yyyy-mm-dd")    private date appointdate; //预定的预成班日期 

比如这个字段,服务端上面用了@datetimeformat注解,这样的话,springmvc手机支持直接传字符串2018-03-03自动转换的。但是,但是,如果你是用client调用,那就不报错啦,报错啦。所以使用的时候,一定要注意啊,一定要注意啊。

小结:虽然fiegn有很多坑,但咱不能说feign不好用。毕竟他比resttemplate或者httpclient还是优雅很多的,能够简化很多东西,负载均衡也做得不错,毕竟在本地就可以做。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。

本文发布于:2023-04-06 03:46:40,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/7637254ae734cb3c3db9486eee109a61.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:Springcloud feign传日期类型参数报错的解决方案.doc

本文 PDF 下载地址:Springcloud feign传日期类型参数报错的解决方案.pdf

标签:注解   参数   报错   类型
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图