Jackson3.x(SpringBoot4.0)迁移ObjectMapper至JsonMapper及日期配置
Jackson 3.x(Spring Boot 4.0)升级:ObjectMapper配置迁移问题
我正在将应用升级至Jackson 3.x(搭配Spring Boot 4.0)。在Jackson 2中,我配置了一个ObjectMapper Bean,手动为JavaTimeModule设置了特定的DateTimeFormatter模式,同时开启/关闭了多项特性。
Jackson 3的核心变化包括:
- ObjectMapper变为不可变对象,需使用构建者模式创建
- 包名从
com.fasterxml.jackson改为tools.jackson - JavaTimeModule(JSR310时间支持)默认已集成,无需手动注册基础模块
原有Jackson 2配置代码如下:
@Bean public ObjectMapper objectMapper() { JavaTimeModule module = new JavaTimeModule(); ObjectMapper mapper = new ObjectMapper(); module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME)); module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ISO_DATE_TIME)); module.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ISO_DATE)); module.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ISO_DATE)); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true); mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); mapper.registerModule(module); mapper.setSerializationInclusion(Include.NON_NULL); return mapper; }
请问:
- 如何使用Jackson 3的新Builder API重建上述特定配置(重点是LocalDateTime和LocalDate的自定义DateTimeFormatter)?
- 针对内置的时间支持,能否直接添加自定义序列化/反序列化,还是仍需注册模块?
迁移方案与解答
1. 使用Jackson 3 Builder API重构配置
Jackson 3中,ObjectMapper的构建必须通过ObjectMapper.builder()完成,同时注意包名的替换。以下是对应原有配置的重构代码:
import tools.jackson.databind.ObjectMapper; import tools.jackson.databind.DeserializationFeature; import tools.jackson.databind.SerializationFeature; import tools.jackson.databind.SerializationInclusion; import tools.jackson.datatype.jsr310.JavaTimeModule; import tools.jackson.datatype.jsr310.deser.LocalDateDeserializer; import tools.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import tools.jackson.datatype.jsr310.ser.LocalDateSerializer; import tools.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import java.time.format.DateTimeFormatter; @Bean public ObjectMapper objectMapper() { // 创建JavaTimeModule并添加自定义序列化/反序列化器 JavaTimeModule javaTimeModule = new JavaTimeModule(); javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME)); javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ISO_DATE_TIME)); javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ISO_DATE)); javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ISO_DATE)); // 使用Builder模式构建ObjectMapper return ObjectMapper.builder() // 注册自定义配置后的JavaTimeModule .registerModule(javaTimeModule) // 配置反序列化特性 .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) // 配置生成器特性 .enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN) // 配置序列化特性 .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) // 设置序列化包含策略 .serializationInclusion(SerializationInclusion.NON_NULL) .build(); }
2. 自定义时间序列化/反序列化的方式
Jackson 3默认集成了JavaTimeModule,但如果需要替换特定时间类型的序列化/反序列化逻辑,有两种可行方式:
- 方式一:通过模块注册(推荐):如上述代码所示,创建JavaTimeModule实例,添加自定义的序列化器/反序列化器后注册到Builder中。这种方式会覆盖默认模块中对应类型的处理逻辑,保持配置的集中性,和Jackson 2的习惯一致。
- 方式二:直接通过Builder配置:可以使用Builder的
serializerByType()和deserializerByType()方法直接指定类型对应的序列化/反序列化器,无需显式创建模块:
return ObjectMapper.builder() .serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ISO_DATE_TIME)) .deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME)) // 其他配置... .build();
两种方式都能实现需求,但模块注册的方式更适合批量配置多个时间类型的处理逻辑,维护性更好。
内容的提问来源于stack exchange,提问作者lak
相关产品推荐
相关产品推荐

