springboot中json转换LocalDateTime失败的bug解决过程
环境:jdk1.8、maven、springboot
问题:前端通过json传了一个日期:date:2019-03-01(我限制不了前端开发给到后端的日期为固定格式,有些人就是这么不配合),
而springboot中默认使用jackson做json序列化和反序列化,后台接收数据时将日期字符串转成LocalDateTime时,会报错:
Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.LocalDateTime` from String "2019-03-01":Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2019-03-01' could not be parsed at index 10 at [Source: (PushbackInputStream); line: 1, column: 10] (through reference chain: com.XXX.vo.XXXExtVo["date"])
at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:1549)
at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:911)
at com.fasterxml.jackson.datatype.jsr310.deser.JSR310DeserializerBase._handleDateTimeException(JSR310DeserializerBase.java:80)
at com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer.deserialize(LocalDateTimeDeserializer.java:84)
at com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer.deserialize(LocalDateTimeDeserializer.java:39)
解决过程:
1.通过百度,参考了大神的解决方法:https://blog.csdn.net/a13794479495/article/details/83892829
2.maven引入依赖
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.9.7</version>
</dependency>
3.增加配置类:LocalDateTimeSerializerConfig
@Configuration
public class LocalDateTimeSerializerConfig {
@Bean
public ObjectMapper serializingObjectMapper() {
JavaTimeModule module = new JavaTimeModule();
LocalDateTimeDeserializer dateTimeDeserializer = new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
module.addDeserializer(LocalDateTime.class, dateTimeDeserializer);
return Jackson2ObjectMapperBuilder.json().modules(module)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS).build();
}
}
4.由于自定义的LocalDateTimeDeserializer反序列化器只能设置一种格式:yyyy-MM-dd HH:mm:ss,所以我遇到的问题还是没有解决
5.对程序进行debug,发现反序列化操作是由LocalDateTimeDeserializer中的deserialize()方法进行反序列化操作的:
public LocalDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException {
if (parser.hasTokenId(6)) {//核心代码
String string = parser.getText().trim();
if (string.length() == 0) {
return null;
} else {
try {
if (this._formatter == DEFAULT_FORMATTER && string.length() > 10 && string.charAt(10) == 'T') {
return string.endsWith("Z") ? LocalDateTime.ofInstant(Instant.parse(string), ZoneOffset.UTC) : LocalDateTime.parse(string, DEFAULT_FORMATTER);
} else {
return LocalDateTime.parse(string, this._formatter);
}
} catch (DateTimeException var12) {
return (LocalDateTime)this._handleDateTimeException(context, var12, string);
}
}
} else {
if (parser.isExpectedStartArrayToken()) {
JsonToken t = parser.nextToken();
if (t == JsonToken.END_ARRAY) {
return null;
}
.........
.........
.........
return (LocalDateTime)this._handleUnexpectedToken(context, parser, "Expected array or string.", new Object[0]);
}
}
}
6.自定义一个MyLocalDateTimeDeserializer反序列化器(复制原来LocalDateTimeDeserializer类中的所有代码,粘贴到自定义的MyLocalDateTimeDeserializer中,修改构造器名及静态域中的相关代码)
7.然后修改MyLocalDateTimeDeserializer中的deserialize()方法
//这里只是简单的根据前端传过来的日期字符串进行简单的处理,然后再进行类型转换
//这段代码中有很多漏洞,只是针对常用格式做了简单处理,请慎用!或自己做更全面的考虑并相应的修改!(只是提供了这样一种解决思路)
public LocalDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException {
if (parser.hasTokenId(6)) {
String string = parser.getText().trim().replace("/", "-");//yyyy/MM/dd替换为yyyy-MM-dd
if (string.length() == 0) {
return null;
}
try {
if (this._formatter == DEFAULT_FORMATTER && string.length() > 10 && string.charAt(10) == 'T') {
return string.endsWith("Z") ? LocalDateTime.ofInstant(Instant.parse(string), ZoneOffset.UTC) : LocalDateTime.parse(string, DEFAULT_FORMATTER);
} else if (string.length() > 10 && string.charAt(10) == 'T') { //处理yyyy-MM-ddTHH:mm:ss.sssZ的格式
return string.endsWith("Z") ? LocalDateTime.ofInstant(Instant.parse(string), ZoneOffset.UTC) : LocalDateTime.parse(string, DEFAULT_FORMATTER);
} else if (string.length() == 10) {//处理yyyy-MM-dd的格式
return LocalDateTime.parse(string + " 00:00:00", this._formatter);
} else {//配置第三步的时候,设置了时间格式为:yyyy-MM-dd HH:mm:ss
return LocalDateTime.parse(string, this._formatter);
}
} catch (DateTimeException var12) {
return this._handleDateTimeException(context, var12, string);
}
} else {
if (parser.isExpectedStartArrayToken()) {
..........
..........
..........
..........
8.在之前第三步的 LocalDateTimeSerializerConfig 配置文件中,修改第六行的代码为:
MyLocalDateTimeDeserializer dateTimeDeserializer = new MyLocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
9.重启服务,验证是否问题解决。
此文仅为记录个人实践中遇到的问题及解决思路。如有雷同,仅可参考!
springboot中json转换LocalDateTime失败的bug解决过程的更多相关文章
- 记录一次bug解决过程:数据迁移
一 总结 不擅长语言表达,勤于沟通,多锻炼 调试MyBatis中SQL语法:foreach 问题:缺少关键字VALUES.很遗憾:它的错误报的让人找不着北. 二 BUG描述:MyBatis中批量插入数 ...
- 记录一次bug解决过程:eclipse集成lombok插件
一 总结 eclipse集成插件lombok: 启动Spring Boot项目: sublime全局搜索关键字:ctrl + shift + F JDK8中的lambda表达式使用 二 BUG描述:集 ...
- 记录一次bug解决过程:else未补全导致数据泄露和代码优化
一.总结 快捷键ctrl + alt + 四个方向键 --> 倒置屏幕 未补全else逻辑,倒置查询数据泄露 空指针是最容易犯的错误,数据的空指针,可以普遍采用三目运算符来解决 SVN冲突解决关 ...
- 1.JSON 转换对象失败问题 2.spring注入失效
今天做项目中将一个json 字符串转换为对象,但结果怎么都转换不了!——————最后发现问题,原来是因为这个类我给他添加了带参数的构造器!导致转换失败! 在添加一个无参的构造器就好了! 第二个:今天调 ...
- C#中Json转换主要使用的几种方法!
这篇主要介绍2.4.第三种方法使用的比较局限,所以我没有深入学习. 第二种方法 我使用比较多的方式,这个方法是.NET内置的,使用起来比较方便 A.利用serializer获取json的泛型对象 利用 ...
- java中JSON转换
1.JSON介绍 JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度. JSON就是一串字符串 只不过元素会使用特定的符 ...
- 记录一次bug解决过程:velocity中获取url中的参数
一.总结 在Webx的Velocity中获取url中参数:$rundata.getRequest().getParameter('userId') 在Webx项目中,防止CSRF攻击(Cross-si ...
- 记录一次bug解决过程:mybatis中$和#的使用
一.总结 mybatis中使用sqlMap进行sql查询时,经常需要动态传递参数.动态SQL是mybatis的强大特性之一,也是它优于其他ORM框架的一个重要原因.mybatis在对sql语句进行预编 ...
- Eclipse中JSON文件报错,如何解决?
eclipse里面的JSON文件老报错,虽然可以正常运行,但红X看起来就是不爽,怎么解决呢? 这是因为Eclipse认为JSON文件不需要注释,所以报的编译错误,我们可以通过Eclipse的设置把它的 ...
随机推荐
- 同步工具类—— CountDownLatch
本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 CountDownLatch简介 CountDownLa ...
- 一个不错的intellj 相关的博客
http://my.oschina.net/lujianing/blog?catalog=3300430
- android29之UI控件的抽屉式实现方法之一(DrawerLayout和NavigationView)
添加依赖 implementation 'com.google.android.material:material:1.2.0-alpha06' 在Layout中创建两个Xml布局文件,header. ...
- Java程序员必备:序列化全方位解析
前言 相信大家日常开发中,经常看到Java对象"implements Serializable".那么,它到底有什么用呢?本文从以下几个角度来解析序列这一块知识点~ 什么是Java ...
- 07-rem
一.什么是rem rem(font size of the root element)是指相对于根元素`的字体大小的单位.它就是一个相对单位. px:一个绝对单位 em:一个相对单位,根据的是当前盒子 ...
- T - Nash Matrix CodeForces - 1316D
题意: 输入n行数,没行由2*n个数,表示一个坐标(x,y). 如果x和y==-1表示从该点(i,j)出发,按照构造的前移动不会停下. 否则就要到点(x,y)处停下. 题解: 首先处理-1 枚举每个 ...
- 在数组添加元素时报错:IndexError: list index out of range
今天第一次发随笔还有许多不足之处,欢迎评论!!! 最近在写一个成语接龙的小游戏,结果在数组添加元素时报错:IndexError: list index out of range 源码: import ...
- Springboot:整合Mybaits和Druid【监控】(十一)
MyBatis默认提供了一个数据库连接池PooledDataSource,在此我们使用阿里提供的Druid数据库连接池 项目下载:https://files.cnblogs.com/files/app ...
- 将jar包发布到maven中央仓库
将jar包发布到maven中央仓库 最近做了一个swagger-ui的开源项目,因为是采用vue进行解析swagger-json,需要前端支持,为了后端也能方便的使用此功能,所以将vue项目编译后的结 ...
- pytorch实现MLP并在MNIST数据集上验证
写在前面 由于MLP的实现框架已经非常完善,网上搜到的代码大都大同小异,而且MLP的实现是deeplearning学习过程中较为基础的一个实验.因此完全可以找一份源码以参考,重点在于照着源码手敲一遍, ...