Jackson配置处理LocalDateTime、LocalDate等java8时间类型失效的问题解决

目录

前言

一、问题排查过程

1.1 SpringMvc是如何处理请求报文和响应报文

1.2 JacksonConfig配置排查

二、导致Jackson配置失效的原因

2.1 没有addSerializer

2.2 添加了@EnableMvc注解

2.3 另外有地方配置了Jacksonhttpconver覆盖了配置

总结


前言

上一篇文章《使用Jackson进行序列化和反序列化》中指出,Jackson默认是不支持处理java8的时间类型如:LocalDateTime类型会被序列化成带T的时间格式。需要在字段上面添加@DateFomter或者在ObjectMapper中注册JavaTimeModule。但是注册JavaTimeModule的方式我这边一直没有效果,时间类型并没有安装我设置的去格式化。本篇文章是我排查我的配置为何不生效,并最终找到原因使配置生效的过程。


首先我把我的配置先贴出来,有经验的大神应该一眼就看出来导致我时间格式化模块配置没生效的原因了,但是我在排查的时候累计花费时间有一天了。

@Configuration
public class JacksonConfig {@Bean("objectMapper")@Primary@ConditionalOnMissingBean(ObjectMapper.class)public ObjectMapper getObjectMapper(Jackson2ObjectMapperBuilder builder) {ObjectMapper mapper = builder.build();// 日期格式mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));//GMT+8//map.put("CTT", "Asia/Shanghai");mapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));JavaTimeModule javaTimeModule = new JavaTimeModule();javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));javaTimeModule.addSerializer(new LocalTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN)));javaTimeModule.addSerializer(new LocalDateSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.CHINESE_DATE_PATTERN)));javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN)));mapper.registerModule(javaTimeModule);//Include.NON_NULL 属性为NULL 不序列化//ALWAYS // 默认策略,任何情况都执行序列化//NON_EMPTY // null、集合数组等没有内容、空字符串等,都不会被序列化//NON_DEFAULT // 如果字段是默认值,就不会被序列化//NON_ABSENT // null的不会序列化,但如果类型是AtomicReference,依然会被序列化mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);//允许字段名没有引号(可以进一步减小json体积):mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);//允许单引号:mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);// 允许出现特殊字符和转义符//mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);这个已经过时。mapper.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);//允许C和C++样式注释:mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);//序列化结果格式化,美化输出mapper.enable(SerializationFeature.INDENT_OUTPUT);//枚举输出成字符串//WRITE_ENUMS_USING_INDEX:输出索引mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);//空对象不要抛出异常:mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);//Date、Calendar等序列化为时间格式的字符串(如果不执行以下设置,就会序列化成时间戳格式):mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);//反序列化时,遇到未知属性不要抛出异常:mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);//反序列化时,遇到忽略属性不要抛出异常:mapper.disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);//反序列化时,空字符串对于的实例属性为null:mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);return mapper;}
}

我在网上找了很多方法,但是都没有解决我的问题,所以没办法只能想着静下心来,通过查看源码的方式来排查问题了 

一、问题排查过程

1.1 SpringMvc是如何处理请求报文和响应报文

这个我之前的文章有写过,这里就直接引用之前的文章了《深入探究Spring MVC如何处理请求报文和响应报文》根据文章中的内容,处理响应报文的地方是在RequestResponseBodyMethodProcessor#handleReturnValue中。这这里的逻辑的意思就是根据请求头和响应头里面的类型type找到处理响应报文的HttpMessageConverter。

这里直接看结果,最终用来序列化的HttpMessageConvertObjectMapper中的LocalDateTimeSerializer中根本就没有formatter,说明在config中配置的JavaTimeModel并没有生效。但是其他的配置却生效了。

通过上面的分析,可以推断出肯定是MappingJackson2HttpMessageConverter在生成的时候并没有将我在ObjectMapperConfig中配置的JavaTimeModel给带进去。

1.2 JacksonConfig配置排查

  通过上面的排查,知道JavaTimeModel配置未生效,但是其它的配置却是没问题的,所以JacksonConfig中的其它配置是没问题的。下面要排查只能看MappingJackson2HttpMessageConverter生成的地方了这时候我想起了上次也试了一个配置的方法是有效的,就是在Jackson2ObjectMapperBuilder上直接注册model。直接注册model有效,在ObjectMapper上注册就没效果。难道是Jackson2ObjectMapperBuilder没有读取ObjectMapper中的配置,或者是注册之前已经读取了。

想到这里我就想点开这一段代码看一下

ObjectMapper mapper = builder.build();

因为我怀疑build方法是重新创建了一个对象返回了(其实这个想法有点荒谬,重新创建一个就有两个ObjectMapper了,那就是一个ObjectMapper配置一半了)。 所以我就进入代码一探究竟。

大概的意思是Model已经注册好了,所以是build方法不能调用。所以后面我就将配置改成

ObjectMapper mapper = new ObjectMapper();

果然就配置生效了。 

二、导致Jackson配置失效的原因

2.1 没有addSerializer

如果配置Jackson的时候,只是添加了JavaTimeModel,是不会生效的。需要添加LocalDateTimeSerializerLocalDateTimeDeserializerLocalTimeSerializerLocalDateDeserializerLocalDateSerializerLocalTimeDeserializer才会够成功序列化和反序列化时间类型。

2.2 添加了@EnableMvc注解

直接参考这个《jackson全局配置没有生效》

2.3 另外有地方配置了Jacksonhttpconver覆盖了配置

需要自己找到其它配置的地方,或者在配置上添加@Primary注解


总结

本文主要是上个章节留下来的问题,关于builder.build()导致model已经被加载过了的问题似乎我没有说清楚,主要是也不想花时间深究了,有空再去看看MappingJackson2HttpMessageConverter初始化的过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/807725.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C/C++的内存管理

栈帧最主要的作用就是存储局部数据 C语言中动态内存管理方式 C语言动态内存管理 该篇详细的讲述了C语言动态内存管理的使用,不太懂的小伙伴可以去了解一下 C中动态内存管理方式 首先,C语言内存管理的方式在C中可以继续使用。但有些地方就无能为力而且使用…

Volatility-内存取证案例1-writeup--xx大赛

题目提示:flag{中文} 按部就班 (1)获取内存镜像版本信息 volatility -f 文件名 imageinfo 通过上述可知,镜像版本为Win7SP1X64。 (2)获取进程信息: volatility -f 镜像名 --profile第一步获取…

关于AI Agent、RAG技术揭秘:如何让人工智能更懂你?

人工智能技术正以前所未有的速度改变着我们的世界。从深度学习算法的突破到自动化和机器学习技术的进步。在这个变革的时代,几种前沿技术尤其引人注目,其中包括RAG(Retrieval-Augmented Generation)、AI Agent以及多模态技术。 近…

工频磁场抗扰度概述及相关注意事项

工频磁场 是指交流输变电设施产生的磁场,工频又称电力频率。 工频的特点是频率低、波长长;我国工频是50赫(Hz),波长是6000千米(Km) 工频磁场的抗扰度试验(在有电流流过的地方都会伴生磁场,为了检查设备或系…

pmp就是智商税?

首先要明白的是,证书的价值并不在于证书本身,而在于学习过程中所获得的知识和经验,这才是证书真正的价值,是无法被复制的个人能力。 学习和考证都是经验的积累,通过这个过程可以不断地获取所需的知识,并加…

【Cesium学习笔记】一、加载Cesium并更换天地图底图

【Cesium学习笔记】一、加载Cesium 一、加载Cesium二、用Viewer显示地球三、更换天地图底图 Ps:本教程所有代码于同一个工程中,运行npm run dev默认首页为App.vue,只需替换App.vue的内容即可切换不同页面。 一、加载Cesium 本项目使用nvm管理node版本&…

微服务学习2

目录 一.网关路由 1.1.认识网关 1.2网关快速入门 1.2.1.创建项目 1.2.2.引入依赖 1.2.3.启动类 1.2.4.配置路由 1.3.路由过滤 二.网关登录校验 2.1网关请求处理流程 2.2网关过滤器 2.2.2网关过滤器 2.3自定义GlobalFilter 2.4.登录校验 2.4.1.JWT工具 2.4.2.登…

论文发表|《课外语文》期刊点评_投稿指南

论文发表|《课外语文》期刊点评_投稿指南 《课外语文》 知网 3版3300字符 全包 24年11-12月 可加急9-10月,次月出刊 (操作周期2-3个月,文章不是教学类,不要摘要参考文献) 《课外语文》杂志创刊于2002年&#xff…

SpringCloud集成Skywalking链路追踪和日志收集

1. 下载Agents https://archive.apache.org/dist/skywalking/java-agent/9.0.0/apache-skywalking-java-agent-9.0.0.tgz 2. 上传到服务器解压 在Spring Cloud项目中,每部署一个服务时,就拷贝一份skywalking的agent文件到该服务器上并解压。不管是部署…

基于PyAutoGUI图片定位的自动化截图工具--jmeter部分

1、计划 压测完成后需要编写性能测试报告,报告中所需数据截图较多,使用自动化操作方便快捷,就编写一个界面工具以便后续复用。之前编写过loadrunner报告的自动化截图脚本,现在用jmeter也比较多,就编写jmeter部分&#…

3V升9V3串LED驱动恒流WT7012

3V升9V3串LED驱动恒流WT7012 WT7012是一款性能卓越的升压转换器,设计用于驱动多达七串的白光LED。该器件具备宽输入工作电压范围(2-24V),使其在单节或多节锂电池供电的应用中能够稳定提供背光。WT7012支持从3V起升至6V、9V、12V的恒流输出,通…

sqlserver问题记录

今天在利用sql查询数据时出现如下错误 在执行批处理时出现错误。错误消息为: 引发类型为“System.OutOfMemoryException”的异常。 症状 使用 SSMS 运行返回大量数据的 SQL 查询时,会收到类似于以下内容的错误消息: 执行批处理时出错。 错误消息为&…

Linux基础指令补全,权限问题分析—3

一、命令补全: 1.bc指令: 功能:命令行计算器,使用quit退出语法:bc 算式 2.uname指令: 语法:uname 选项功能:uname原来获取电脑或操作系统的相关信息选项: ①-a选项&am…

【IC前端虚拟项目】验证阶段开篇与知识预储备

【IC前端虚拟项目】数据搬运指令处理模块前端实现虚拟项目说明-CSDN博客 从这篇开始进入验证阶段,因为很多转方向的小伙伴是转入芯片验证工程师方向的,所以有必要先做一个知识预储备的说明,或者作为验证入门的一个小指导吧。 在最开始&#…

如何做好2024年中央企业内部控制体系建设与监督工作

面对日益复杂的经济环境和全球一体化的挑战,中央企业作为国家经济的中流砥柱,必须不断提升内部控制体系的建设与执行水平。随着2024年的脚步逼近,中央企业需围绕国家宏观政策,积极采纳智能化技术,强化内控体系&#xf…

Redis 的数据结构和内部编码

Redis的 5 种数据类型 Redis 底层在实现上述数据结构的时候,会在源码层面,针对上述实现进行 特定的优化 ,来达到节省时间/节省空间效果 特定的优化:内部的具体实现的数据结构,在特定场景下,不是其对应的标准…

运动控制卡/运动控制器的ZCAN总线ZMIO310扩展模块使用

本节课程主要分为八个部分给大家讲解ZCAN扩展模块的使用,分别是: 一、ZMIO310系列扩展模块介绍 二、ZMIO310-CAN通讯模块的接线 三、ZMIO310-CAN通讯模块介绍及拨码开关设置 四、ZMIO310子模块接线参考 五、ZMIO310-CAN扩展模块功能验证 六、ZMIO3…

新手怎么正确地做抖音小店?入门级教程来了,建议认真阅读!

大家好,我是电商糖果 新手做抖音小店,不懂小店的运营,总是容易走弯路,踩坑。 糖果这里就给大家带来,新手正确的入门级运营教程。 近期刚开店的朋友,建议认真阅读! 第一步:基础后台…

探索艺术的新领域——3D线上艺术馆如何改变艺术作品的传播方式

在数字化时代的浪潮下,3D线上艺术馆成为艺术家们展示和传播自己作品的新平台。不仅突破了地域和物理空间的限制,还提供了全新的互动体验。 一、无界限的展示空间:艺术家的新展示平台 3D线上艺术馆通过数字化技术,为艺术家提供了一…

Java List基础篇

目录 前言一、常用List1.1 List1.1.1 特点1.1.2 常用API 1.2 ArrayList1.2.1 特点1.2.2 使用 1.3 LinkedList1.3.1 特点1.3.2 使用 1.4 CopyOnWriteArrayList1.4.1 特点1.4.2 使用 1.5 Arrays.asList()1.5.1 特点1.5.2 使用 二、对比总结 前言 一、常用List 1.1 List List是…