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,一经查实,立即删除!

相关文章

java es相关操作

一.es 后期修改分片数量 在Elasticsearch中一旦索引创建后,分片的数量就不能直接更改。如果需要更改分片的数量,你需要按照以下步骤操作: 创建一个新的索引,并指定所需的分片数量。 将旧索引的数据复制到新索引中。 关闭旧索引…

K8-Prometheus部署与应用

Prometheus //Prometheus 概述: Prometheus 是一个开源的服务监控系统和时序数据库,其提供了通用的数据模型和快捷数据采集、存储和查询接口。它的核心组件 Prometheus server 会定期从静态配置的监控目标或者基于服务发现自动配置的目标中进行拉取数据…

C/C++的内存管理

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

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

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

第2章:计算机系统基础知识-文字摘抄(上篇)

计算机系统的分类示意图 计算机系统 嵌入式计算机 电信设备 基站网络交换移动终端 家用电子设备 视听设备厨卫电器 可穿戴电子设备医疗设备交通设备国防设备金融设备 通用计算机 个人计算机 台式电脑平板电脑 网络服务器 云存储云计算 超级计算机 计算机硬件组成 处理器存…

Python 爬虫基础:利用 BeautifulSoup 解析网页内容

1. 理解 Python 爬虫基础 在当今信息爆炸的时代,网络上充斥着海量的数据,而网络爬虫作为一种数据采集工具,扮演着至关重要的角色。网络爬虫是一种自动化的程序,可以模拟浏览器访问网页,获取所需信息并进行提取和整合。…

【EasyExcel使用两个Java对象来接受一个excel文件】

需求背景: 有时候上传文件想要写一个通用的逻辑,就是说,这个excel前面几个字段是基础字段,后面几个字段是定制字段。 那么为了以后上传不同的文件,就需要编写不同的listener去解析每种不同的excel文件,但是…

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

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

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

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

vue监听键盘回车事件的三种方法..

方法一&#xff1a; keydown‘show()’ 当然我们传个$event 也可以在函数中获 ev.keyCode if(ev.keyCode13){ alert(‘你按了回车键&#xff01;’) } 方法二&#xff1a; <input type“text” keyup.enter“show()”>回车执行 <input type“text” keydown.up‘sh…

pmp就是智商税?

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

基线核查与系统加固:构筑坚实基础防御的双刃剑

引言 网络安全在当今信息社会扮演着不可或缺的角色&#xff0c;而安全基线核查和系统加固作为网络安全防御的基础工作至关重要。本文将深入探讨安全基线核查和系统加固的定义、必要性&#xff0c;以及它们在安全管理中的重要要求。旨在强调这些基础工作在构建健壮网络安全体系…

网络协议学习——IP协议

IP&#xff08;Internet Protocol&#xff0c;互联网协议&#xff09;是网络中最基本的协议之一&#xff0c;负责在互联网中进行数据包的传输。下面是对IP协议的详细讲解&#xff1a; IP协议的作用 IP协议是在网络层&#xff08;第三层&#xff09;上工作的协议&#xff0c;它的…

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

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

[xboard]real6410-6.2 移植kernel网络驱动

文章目录 硬件电路软件配置问题1问题2问题3问题4功能测试硬件电路 核心板,使用DM9000A [图片] 软件配置 问题1 / # / # ifconfig ifconfig: /proc/net/dev: No such file or directory ifconfig: socket: Fun

微服务学习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.登…

基于springboot的编程训练系统源码数据库

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了编程训练系统的开发全过程。通过分析编程训练系统管理的不足&#xff0c;创建了一个计算机管理编程训练系统的方案。文章介绍了编程训练系统的系统分析部分&…

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

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

Linux入门常见指令

ls指令 语法&#xff1a; s [ 选项 ] 功能&#xff1a;想查看当前目录的所有子文件与文件夹&#xff0c;直接输入ls然后回车即可&#xff0c;但是ls可以尾接许多选项 例如&#xff1a; ls -a&#xff0c;这个是显示当前目录的所有文件&#xff0c;包括隐藏文件 诸如此类的常用…

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项目中&#xff0c;每部署一个服务时&#xff0c;就拷贝一份skywalking的agent文件到该服务器上并解压。不管是部署…