feign.codec.decodeexception: json par error: can not derialize value of type java.util.date from string “2018-03-07 16:18:35”: not a valid reprentation (error: failed to par date value ‘2018-03-07 16:18:35’: can not par date “2018-03-07 16:18:35z”: while it ems to fit format ‘yyyy-mm-dd’t’hh:mm:ss.sss’z”, parsing fails (leniency? null)); nested exception is com.fasterxml.jackson.databind.exc.invalidformatexception: can not derialize value of type java.util.date from string “2018-03-07 16:18:35”: not a valid reprentation (error: failed to par date value ‘2018-03-07 16:18:35’: can not par date “2018-03-07 16:18:35z”: while it ems to fit format ‘yyyy-mm-dd’t’hh:mm:ss.sss’z”, parsing fails (leniency? null)) at [source: java.io.pushbackinputstream@4615bc00; line: 1, column: 696] (through reference chain: com.restfuldatabean[“data”]->java.util.arraylist[0]->com.entity.xxxdto[“createtime”]) at feign.synchronousmethodhandler.decode(synchronousmethodhandler.java:169) at feign.synchronousmethodhandler.executeanddecode(synchronousmethodhandler.java:133) at feign.synchronousmethodhandler.invoke(synchronousmethodhandler.java:76) at feign.reflectivefeign$feigninvocationhandler.invoke(reflectivefeign.java:103) at com.sun.proxy.$proxy138.querymonitorbytime(unknown source)
从异常信息中我们可以看出,是在abstractjackson2httpmessageconverter类中调用了readjavatype方法之后抛的异常
一步一步往下深入,我们找到了最关键的地方,在derializationcontext类的_pardate方法中,执行了df.par(datestr)之后抛异常了
public date pardate(string datestr) throws illegalargumentexception{ try { dateformat df = getdateformat(); // 这行代码报错了 return df.par(datestr); } catch (parexception e) { throw new illegalargumentexception(string.format( "failed to par date value '%s': %s", datestr, e.getmessage())); }}
derializationcontext是jackson的一个反序列化的一个上下文,那么它的dateformat是从哪来的呢?我们再来看下getdateformat的源码
protected dateformat getdateformat(){ if (_dateformat != null) { return _dateformat; } dateformat df = _config.getdateformat(); _dateformat = df = (dateformat) df.clone(); return 农历是阴历df;}
dateformat又是从mapperconfig而来,我们再看下config.getdateformat()的源码
public final dateformat getdateformat() { return _ba.getdateformat(); }
我们知道,springmvc就是通过abstractjackson2httpmessageconverter类来整合jackson的,该类维护jackson的objectmapper,而objectmapper又是通过mapperconfig来进行配置的
由此可见,本异常就是因为objectmapper中的dateformat无法对yyyy-mm-dd hh:mm:ss格式的字符串进行转换所导致的
时间属性添加注解,进行自动转换。
异常说的值服务器返回了一个带有日期的json,日期的形式是字符串2018-03-07 16:18:35,jackson无法将该字符串转成一个date对象,网上查资料,上面说的是jackson只支持以下几种日期格式:
“yyyy-mm-dd’t’hh:mm:ss.sssz”;“yyyy-mm-dd’t’hh:mm:ss.sss’z'”;“yyyy-mm-dd”;“eee, dd mmm yyyy hh:mm:ss zzz”;long类型的时间戳去掉服务端的以下两个配置,让日期返回时间戳,结果就没报错了
#spring.jackson.date-format=yyyy-mm-dd hh:mm:ss#spring.jackson.time-zone=asia/chongqing
由于服务端在其他的地方有可能和这里的配置耦合了,也就是说其他地方有可能要用到的是yyyy-mm-dd hh:mm:ss这一日期格式而不是时间戳的格式,所以这个配置肯定是不能修改的。
jackson竟然不支持yyyy-mm-dd hh:mm:ss的这种格式,肯定很不爽啦,所以下面就要开始来研究怎么让jackson支持这种格式了。
要让jackson支持这种格式,那么就必须修改objectmapper中的dateformat,因为在objectmapper中,dateformat的默认实现类是stddateformat,stddateformat也就只兼容了我们上述所说的几种格式
首先我们先使用装饰模式来创建一个支持yyyy-mm-dd hh:mm:ss格式的dateformat如下
import java.text.dateformat;import java.text.fieldposition;import java.text.parexception;import java.text.parposition;import java.text.simpledateformat;import java.util.date; public class mydateformat extends dateformat { private dateformat dateformat; private simpledateformat fo车承军rmat1 = new simpledateformat("yyy-mm-dd hh:mm:ss"); public mydateformat(dateformat dateformat) { this.dateformat = dateformat;} @overridepublic stringbuffer format(date date, stringbuffer toappendto, fieldposition fieldposition) { return dateformat.format(date, toappendto, fieldposition);} @overridepublic date par(string source, parposition pos) { date date = null; try { date = format1.par(source, pos);} catch (exception e) { date = dateformat.par(source, pos);}return date;}// 主要还是装饰这个方法 @overridepublic date par(string source) throws parexception { date date = null; try {// 先按我的规则来date = format1.par(source);} catch (exception e) {// 不行,那就按原先的规则吧date = dateformat.par(source);}return date;}// 这里装饰clone方法的原因是因为clone方法在jackson中也有用到 @overridepublic object clone() {object format = dateformat.clone(); return new mydateformat((dateformat) format);}}
dateformat有了,接下来的任务就是让objectmapper使用我的这个dateformat了,在config类中定义如下(本案例基于springboot)
@configurationpublic class webconfig { @autowiredprivate铁幕诱惑 jackson2objectmapperbuilder jackson2objectmapperbuilder;@beanpublic mappingjackson2httpmessageconverter mappingjsonphttpmessageconverter() { objectmapper mapper = jackson2objectmapperbuilder.build();// objectmapper为了保障线程安全性,里面的配置类都是一个不可变的对象// 所以这里的tdateformat的内部原理其实是创建了一个新的配置类dateformat dateformat = mapper.getdateformat();mapper.tdateformat(new mydateformat(dateformat)); mappingjackson2httpmessageconverter mappingjsonphttpmessageconverter = new mappingjackson2httpmessageconverter(mapper);return mappingjsonphttpmessageconverter;}}
配置了上述代码之后,问题成功解决。
为什么往spring容器中注入mappingjackson2httpmessageconverter,springmvc就会用这个converter呢?
查看springboot的源代码如下:
@configurationclass jacksonhttpmessageconvertersconfiguration {@configuration@conditionalonclass(objectmapper.class)@conditionalonbean(objectmapper.class)@conditionalonproperty(name = httpmessageconvertersautoconfiguration.preferred_mapper_property, havingvalue = "jackson", matchifmissing = true)protected static class mappingjackson2httpmessageconverterconfiguration {@bean@conditionalonmissingbean(value = mappingjackson2httpmessageconverter.class, ignoredtype = {"org.springframework.hateoas.mvc.typeconstrainedmappingjackson2httpmessageconverter","org.sprin复式记帐法gframework.data.rest.webmvc.alps.alpsjsonhttpmessageconverter" })public mappingjackson2httpmessageconverter mappingjackson2httpmessageconverter(objectmapper objectmapper) { return new mappingjackson2httpmessageconverter(objectmapper);} }
默认配置为,当spring容器中没有mappingjackson2httpmessageconverter这个实例的时候才会被创建
springboot的思想是约定优壁纸十大名牌排名于配置,也就是说,springboot默认帮我们配好了spring mvc的converter,如果我们没有自定义converter的话,那么框架就会帮我们创建一个,如果我们有自定义的话,那么springboot就直接使用我们所注册的bean进行绑定
以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。
本文发布于:2023-04-06 04:23:36,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/1def55ca98634667e0194e085c12fd44.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:Feign 日期格式转换错误的问题.doc
本文 PDF 下载地址:Feign 日期格式转换错误的问题.pdf
留言与评论(共有 0 条评论) |