springboot日期格式化全局LocalDateTime詳解
springboot 默認(rèn)使用ObjectMapper(jackson)操作對(duì)象的序列化和反序列化
分析
從springboot:3.2.1 web 項(xiàng)目序列化響應(yīng)體的過(guò)程中分析日期格式化問(wèn)題(左側(cè)是請(qǐng)求處理流程,右側(cè)是在流程中使用的一些對(duì)象的來(lái)源)

ObjectMapper與JsonSerializer
根據(jù)上述流程可知,序列化響應(yīng)結(jié)果時(shí)使用的ObjectMapper對(duì)象是由自動(dòng)配置類JacksonAutoConfiguratioin.JacksonObjectMapperConfiguration使用Jackson2ObjectMapperBuilder創(chuàng)建,并注冊(cè)到beanfactory中。

創(chuàng)建ObjectMapper對(duì)象

設(shè)置ObjectMapper對(duì)象的屬性
在Jackson2ObjectMapperBuilder#build方法中創(chuàng)建了ObjectMapper對(duì)象,然后在Jackson2ObjectMapperBuilder#configure方法中對(duì)ObjectMapper對(duì)象設(shè)置了一些屬性。
例如創(chuàng)建JavaTimeModule對(duì)象并將其注冊(cè)給ObjectMapper, 正是在JavaTimeModule的構(gòu)造方法中指定了LocalDateTime的序列化器使用com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer,并將這種關(guān)系使用ObjectMapper#registerModules注冊(cè)給ObjectMapper對(duì)象

在以下方法中創(chuàng)建了com.fasterxml.jackson.datatype.jsr310.JavaTimeModule對(duì)象
private void registerWellKnownModulesIfAvailable(MultiValueMap<Object, Module> modulesToRegister) {
// ...
try {
Class<? extends Module> javaTimeModuleClass = (Class<? extends Module>)
ClassUtils.forName("com.fasterxml.jackson.datatype.jsr310.JavaTimeModule", this.moduleClassLoader);
Module javaTimeModule = BeanUtils.instantiateClass(javaTimeModuleClass);
modulesToRegister.set(javaTimeModule.getTypeId(), javaTimeModule);
}
catch (ClassNotFoundException ex) {
// jackson-datatype-jsr310 not available
}
// ...
}在JavaTimeModule類的構(gòu)造函數(shù)中設(shè)置了LocalDateTime類型和該類型使用的序列化器LocalDateTimeSerializer和反序列化器LocalDateTimeDeserializer的對(duì)應(yīng)關(guān)系

結(jié)論
springboot項(xiàng)目中,使用從beanfactory中獲取的ObjectMapper序列化對(duì)象時(shí),若對(duì)象的字段類型是LocalDateTime,則使用com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer對(duì)字段進(jìn)行序列化,但是其默認(rèn)的日期格式并不是我們想要的。

因此需要干涉上述流程,使用自定義的日期時(shí)間格式

自定義日期格式(全局)
1.直接操作spring容器中的ObjectMapperbean
利用ObjectMapper#registerModule
2.自定義容器中的Jackson2ObjectMapperBuilderbean,達(dá)到間接操作ObjectMapper的目的
從流程圖中可知,容器中的ObjectMapper對(duì)象由Jackson2ObjectMapperBuilder創(chuàng)建(創(chuàng)建者模式),因此自定義Jackson2ObjectMapperBuilder的屬性,會(huì)間接作用到ObjectMapper的屬性
根據(jù)JacksonAutoConfiguration.JacksonObjectMapperBuilderConfiguration源碼可知,創(chuàng)建一個(gè)Jackson2ObjectMapperBuilderCustomizer實(shí)現(xiàn)類,并將其注入到容器中,可對(duì)容器中的Jackson2ObjectMapperBuilder bean進(jìn)行自定義配置

按照上述思路實(shí)現(xiàn)如下(真實(shí)工作中需考慮多個(gè)customizer的順序)

也可以使用modulesToInstall方法

3.向容器中注入com.fasterxml.jackson.databind.Module的實(shí)現(xiàn)類
這是因?yàn)閟pringboot自動(dòng)配置包中已經(jīng)提供了一個(gè)Jackson2ObjectMapperBuilderCustomizer實(shí)現(xiàn)類,在創(chuàng)建該實(shí)現(xiàn)類對(duì)象時(shí),它將從容器中獲取的com.fasterxml.jackson.databind.Modulebean用于自定義配置Jackson2ObjectMapperBuilder

同時(shí),可以看到StandardJackson2ObjectMapperBuilderCustomizer類使用了JacksonProperties的配置,也就說(shuō)可以在配置文件中做些定義的配置

擴(kuò)展
利用配置文件指定java.util.Date類型的格式化
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8這種方式對(duì)java.time.LocalDateTime類型無(wú)效
利用注解指定時(shí)間格式化(局部)
@JsonFormat,對(duì)java.util.Date和java.time.LocalDateTime都有效

@JsonSerialize、@JsonDeserialize,指定使用的序列化器@DateTimeFormat@JsonComponent
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Token過(guò)期實(shí)現(xiàn)自動(dòng)續(xù)期的方法步驟
本文詳細(xì)解析了Token在防止表單重復(fù)提交、身份驗(yàn)證及過(guò)期處理中的應(yīng)用,涵蓋Token的生成流程、過(guò)期機(jī)制及續(xù)期方案,特別介紹了單token與雙token兩種策略,需要的朋友可以參考下2026-05-05
Java基礎(chǔ)之內(nèi)部類與代理知識(shí)總結(jié)
今天帶大家復(fù)習(xí)Java的基礎(chǔ)知識(shí),文中有非常詳細(xì)的介紹及圖文示例,對(duì)正在學(xué)習(xí)Java的小伙伴們很有幫助,需要的朋友可以參考下2021-06-06
SpringBoot中Package打包的實(shí)現(xiàn)小結(jié)
本文詳細(xì)介紹了將SpringBoot項(xiàng)目打包成jar或war,包括jar的默認(rèn)打包、war的內(nèi)嵌tomcat排除和配置,以及部署到外部Tomcat的步驟,適合開(kāi)發(fā)者理解和實(shí)踐項(xiàng)目部署,感興趣的可以了解一下2026-03-03
Spring MVC簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
Spring MVC屬于SpringFrameWork的后續(xù)產(chǎn)品,已經(jīng)融合在Spring Web Flow里面。今天先從寫(xiě)一個(gè)Spring MVC的HelloWorld開(kāi)始,讓我們看看如何搭建起一個(gè)Spring mvc的環(huán)境并運(yùn)行程序,感興趣的朋友一起學(xué)習(xí)吧2017-08-08
java隨機(jī)驗(yàn)證碼生成實(shí)現(xiàn)實(shí)例代碼
這篇文章主要介紹了java隨機(jī)驗(yàn)證碼生成實(shí)現(xiàn)實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-05-05
spring事務(wù)里面開(kāi)啟線程插入報(bào)錯(cuò)了是否會(huì)回滾
這篇文章主要介紹了spring事務(wù)里面開(kāi)啟線程插入,報(bào)錯(cuò)了是否會(huì)回滾?這是小編遇到一道面試題,題目大概是這個(gè)樣子,今天抽空通過(guò)示例代碼給大家分析下,需要的朋友可以參考下2023-04-04
Java中Integer類常用靜態(tài)方法實(shí)例詳解
在Java編程中Integer類是int基本類型的封裝類,提供了許多方便的功能,這篇文章主要介紹了Java中Integer類常用靜態(tài)方法的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-07-07

