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

news2025/2/25 11:20:02

目录

前言

一、问题排查过程

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.coloradmin.cn/o/1585730.html

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

相关文章

利用alibaba.item_get API接口,跨境电商如何快速获取商品详情?

利用alibaba.item_get API接口,跨境电商可以快速获取商品详情,为业务的开展提供有力支持。alibaba.item_get API接口是阿里巴巴开放平台提供的一项服务,它允许开发者通过调用API接口,获取阿里巴巴平台上商品的详细信息。以下是如何…

QT 线程之movetothread

上文列举了qt中线程的几种方法,其中2种方法最为常见。 这两种方法都少不了QThread类,前者继承于QThread类,后者复合QThread类。 本文以实例的方式描述了movetothread()这种线程的方法,将QObject的子类移动…

如何使用Tomcat+cpolar搭建本地站点并发布到公网分享好友远程访问

文章目录 前言1.本地Tomcat网页搭建1.1 Tomcat安装1.2 配置环境变量1.3 环境配置1.4 Tomcat运行测试1.5 Cpolar安装和注册 2.本地网页发布2.1.Cpolar云端设置2.2 Cpolar本地设置 3.公网访问测试4.结语 前言 Tomcat作为一个轻量级的服务器拥有强大功能,由于其可以实…

Python初级第二次作业

一、 def reverse(num):anumt0b0cnumwhile a//10>0:if a%10>0:t1aa//10print(t)for i in range(t,-1,-1):if c%100:b0else:b(c%10)*(10**i)c//10print(b) if bnum:return Trueelse:return Falsedef isPalind(num):kreverse(num)if kTrue:print(f"{num}是回文&…

分类模型决策边界、过拟合、评价指标、PR、ROC曲线

文章目录 1、线性逻辑回归决策边界1.2、使用自定义函数绘制决策边界1.3、三分类的决策边界1.4、多项式逻辑回归决策边界 2、过拟合和欠拟合2.2、欠拟合2.3、过拟合 3、学习曲线4、交叉验证5、泛化能力6、混淆矩阵7、PR曲线和ROC曲线 x2可以用x1来表示 1、线性逻辑回归决策边界 …

【找工作最强助手】全平台自动投简历脚本:(boss、前程无忧、猎聘、拉勾、智联招聘)

get-jobs【工作无忧】 💼自动投简历(Boss直聘、猎聘、拉勾、51job、智联招聘) 项目链接:https://github.com/loks666/get_jobs最新文档以上面的链接为主 特色功能 支持国内全部招聘平台(Boss直聘、猎聘、拉勾、51job、智联招聘)内置driver驱动&#xf…

各种拟合算法整理

各种拟合算法整理 1. 最小二乘法2. 霍夫变换3. RANSAC算法 本篇将介绍最小二乘法(Least Square)、霍夫变换(Hough Transform)和RANSAC(random sample consensus,随机抽样一致性算法)算法的原理、应用和代码。 如果已经知道了一组可靠的点,可以直接使用最…

数据绑定多级对象属性时的报错解决

数据绑定多级对象属性时的报错解决 (1)例子如下: (2)当syncObjForm被后台数据赋值时,会产生报错: (3)原因就是: 模板在渲染时,读取对象中的某个…

Apache SeaTunnel 社区 3 月月报

各位热爱 SeaTunnel 的小伙伴们,SeaTunnel 社区 3 月月报来啦!这里将记录 SeaTunnel 社区每个月的重要更新,并评选出月度之星,欢迎关注。 SeaTunnel 月度 Merge Stars 感谢以下小伙伴 3 月为 Apache SeaTunnel 做的精彩贡献&…

家用洗地机哪个型号推荐?盘点四款最高性价比机型

在当今快节奏的生活中,有娃家庭的地面打扫已经成为日常的卫生保洁,对于许多家庭来说,洗地机成为了必备的助手。然而,面对市场上琳琅满目的洗地机品牌和型号,我们通常为选择哪款好?哪款性价比高而犯难。因为…

Linux系统本地搭建DbGate数据库并结合内网穿透实现无公网IP远程连接

文章目录 1. 安装Docker2. 使用Docker拉取DbGate镜像3. 创建并启动DbGate容器4. 本地连接测试5. 公网远程访问本地DbGate容器5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定公网地址远程访问 本文主要介绍如何在Linux Ubuntu系统中使用Docker部署DbGate数据库管理工…

Python使用requests+excel进行接口自动化测试!

在当今的互联网时代中,接口自动化测试越来越成为软件测试的重要组成部分。Python是一种简单易学,高效且可扩展的语言,自然而然地成为了开发人员的首选开发语言。而requests和xlwt这两个常用的Python标准库,能够帮助我们轻松地开发…

Java基础入门--第十二章--多线程

多线程 12.1 进程与进程12.1.1 进程12.1.2 线程 12.2 线程的创建12.2.1 继承Thread类创建多线程12.2.2 实现Runnable接口创建多线程12.2.3 实现Callable接口创建多线程12.2.4 Thread类与Runnable接口实现多线程的对比12.2.5 后台线程 12.3 线程的生命周期及状态转换12.4 线程操…

谷歌浏览器网页自动刷新插件

谷歌浏览器网页自动刷新插件下载:https://www.123pan.com/s/f43eVv-CO7Kd.html 效果图(win和mac系统同样操作) 1.打开谷歌浏览器,点击头像旁边的三点,点击扩展程序,点击管理扩展程序。 2.打开开发者模式&a…

用 ElementPlus 的日历组件 Calendar 自定义渲染

文章目录 需求分析1. 英文改为中文2. 修改样式3. 自定义头部4. 增删改功能接入 需求 使用 ElementPlus中的 Calendar 组件完成自定义渲染 分析 1. 英文改为中文 转为中文的方式&#xff1a;用 ElementPlus的日历组件如何改为中文 2. 修改样式 附源码 <template><…

【YOLOv8】Yolov5和Yolov8网络结构的分析与对比

目录 一 YOLOv5 二 YOLOv8 yolo通常采用backbone-neck-head的网络结构。 Backbone 主要负责从输入图像中提取高层次的语义特征,常包含多个卷积层和池化层&#xff0c;构建了一个深层次的特征提取器。Neck通常用来进一步整合与调整backbone提取的特征&#xff0c;有利于将不同…

内容创作策略:打造影响力强大的技术博客

CSDN的朋友你们好&#xff0c;我是未来&#xff0c;今天给大家带来专栏【程序员博主教程&#xff08;完全指南&#xff09;】的第6篇文章——“博客内容创作策略”。本文为技术博主提供了一个精简的内容创作策略指南&#xff0c;涵盖了设定目标、分析竞争、关键词研究、内容规划…

PMP与软考的区别看不懂?看懂这五点,小白都知道怎么选!

如果你心怀抱负&#xff0c;不甘心做项目“小透明” 如果你遇到年龄危机&#xff0c;进阶管理无门道&#xff1f; 如果你是技术&#xff0c;管理项目有如盲人摸象&#xff1f;可以考PMP! 如果你准备想攒积分&#xff0c;轻松落户 如果你想评职称&#xff0c;获得专业技术职务 如…

【环境搭建】(五)Ubuntu22.04安装cuda_11.8.0+cudnn_8.6.0

一个愿意伫立在巨人肩膀上的农民...... 设备配置&#xff1a; 一、安装GCC 安装cuda之前&#xff0c;首先应该安装GCC&#xff0c;安装cuda需要用到GCC&#xff0c;否则报错。可以先使用下方指令在终端查看是否已经安装GCC。 gcc --version 如果终端打印如下则说明已经安装…

【浏览器】Google Chrome浏览器打开自动访问网址 gw1.dhwz333.top

目录 [TOC](目录) 问题描述1、查看谷歌浏览器信息2、查看快捷方式属性2、查找注册表3、重装浏览器 解决方案一、使用360系统急救箱进行杀毒步骤1、下载360系统急救箱方式1、直接下载方式2、从360杀毒中打开&#xff0c;需要联网2.1、打开“功能大全”2.2、打开系统急救箱 步骤2…