Jackson全局配置序列化时间对LocalDateTime不生效

结论

对于 Java 8 的日期时间类型,如 LocalDateTime,全局的 spring.jackson.date-format 属性并不适用,因为这些类型通常需要特定的序列化器来格式化。需要添加配置类来添加对LocalDateTime的支持。

问题

VO的属性有一个创建时间和一个更新时间。

public class xxVO implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private LocalDateTime createAt;
    private LocalDateTime updateAt;
}

yaml中添加了日期序列化格式为yyyy-MM-dd HH:mm:ss。

 jackson:
   default-property-inclusion: non_null
   date-format: yyyy-MM-dd HH:mm:ss
   time-zone: Asia/Shanghai

但是从返回结果来看并没有生效。

{
"createAt": "2024-06-01T09:38:17",
"updateAt": "2024-06-01T15:11:43"
}

解决方案

  1. 引入依赖
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.13.0</version> 
</dependency>

配置ObjectMapper

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        JavaTimeModule module = new JavaTimeModule();
        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(module);
        return mapper;
    }
}

但是这种方式会导致yaml中的配置不生效。比如我的配置中设置了时区和对null值的处理,都需要一一在ObjectMapper中配置,非常麻烦。

然后想到可不可以通过修改框架里的ObjectMapper来达到这个目的。

@Component
public class ObjectMapperCustomizer implements ApplicationListener<ContextRefreshedEvent> {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        ObjectMapper mapper = event.getApplicationContext().getBean(ObjectMapper.class);
        JavaTimeModule module = new JavaTimeModule();
        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        mapper.registerModule(module);
    }
}

这里我们监听ContextRefreshedEvent事件,然后从ApplicationContext中直接获取ObjectMapper。通过debug测试,确实拿到了ObjectMapper的Bean对象,也设置了值但是并没有生效(知道原因的同学欢迎在评论区指出)。

配置Module

后来在一篇博客(底部有链接)中看到了这个问题的另一个解决方案,试了一下生效了,配置如下。

@Configuration
public class JacksonConfig {
    @Value("${spring.jackson.date-format:'yyyy-MM-dd HH:mm:ss'}")
    private String pattern;

    @Bean
    public Module javaTimeModule() {
        JavaTimeModule module = new JavaTimeModule();
        // 为 LocalDateTime 设置自定义序列化器
        LocalDateTimeSerializer localDateTimeSerializer = new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
        LocalDateTimeDeserializer localDateTimeDeserializer = new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(pattern));
        module.addSerializer(LocalDateTime.class, localDateTimeSerializer);
        module.addDeserializer(LocalDateTime.class, localDateTimeDeserializer);
        return module;
    }
}

这个配置可以和jackson的yaml配置一块生效。我的yaml配置还可以继续使用,还新增了对LocalDataTime的支持,完美。

引用

https://www.51cto.com/article/777079.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值