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

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用 Jackson 库来序列化 LocalDateTime 对象。首先,确保你已经在项目中引入了 Jackson 的依赖。然后,按照以下步骤进行序列化: 1. 创建一个 ObjectMapper 对象,它是 Jackson 库的核心类之一,用于执行序列化和反序列化操作。 2. 在 ObjectMapper 对象上设置适当的配置,以便正确地处理 LocalDateTime 类型。 3. 将 LocalDateTime 对象传递给 ObjectMapper 的 writeValueAsString() 方法,该方法将返回一个包含序列化结果的 JSON 字符串。 以下是一个示例代码: ```java import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import java.time.LocalDateTime; public class LocalDateTimeSerializer { public static void main(String[] args) throws Exception { // 创建 ObjectMapper 对象 ObjectMapper objectMapper = new ObjectMapper(); // 注册 JavaTimeModule 模块,以支持 LocalDateTime 类型 objectMapper.registerModule(new JavaTimeModule()); // 创建 LocalDateTime 对象 LocalDateTime dateTime = LocalDateTime.now(); // 序列化为 JSON 字符串 String jsonString = objectMapper.writeValueAsString(dateTime); // 输出序列化结果 System.out.println(jsonString); } } ``` 运行以上代码,你将会得到一个包含序列化后的 LocalDateTime 对象的 JSON 字符串。请注意,Jackson 库对于 LocalDateLocalTime 和 LocalDateTime 类型的序列化和反序列化需要添加 `com.fasterxml.jackson.datatype:jackson-datatype-jsr310` 的依赖。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值