Java:jackson处理LocalDateTime序列化的时候报错InvalidDefinitionException

问题描述

jackson处理LocalDateTime序列化的时候报错

ObjectMapper mapper = new ObjectMapper();

mapper.writeValueAsString(LocalDateTime.now());

报错信息

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
Java 8 date/time type `java.time.OffsetDateTime` not supported by default: 
add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling

如果处理Date对象是不会报错的

ObjectMapper mapper = new ObjectMapper();

mapper.writeValueAsString(new Date());
// 1684480558531

解决方法

按照异常信息提示,引入模块com.fasterxml.jackson.datatype:jackson-datatype-jsr310

引入依赖

<!-- json -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.4</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.13.4</version>
</dependency>

注册JavaTimeModule

ObjectMapper mapper = new ObjectMapper();

// 已过时
// mapper.registerModule(new JSR310Module());
// Jackson 2.7 之后使用JavaTimeModule
mapper.registerModule(new JavaTimeModule());

// 默认输出
mapper.writeValueAsString(LocalDateTime.now())
[2023,5,19,15,21,57,337000000]

发现输出的格式不太对,进一步优化

ObjectMapper mapper = new ObjectMapper();

JavaTimeModule javaTimeModule = new JavaTimeModule();
// 设置序列化格式
javaTimeModule.addSerializer(LocalDateTime.class,
        new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
mapper.registerModule(javaTimeModule);

try {
    System.out.println(mapper.writeValueAsString(LocalDateTime.now()));
    // "2023-05-19 15:29:01"
} catch (JsonProcessingException e) {
    e.printStackTrace();
}

完整测试代码

package com.example.demo;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class JsonTest {
    @Test
    public void testJavaTimeModule() {
        ObjectMapper mapper = new ObjectMapper();

        JavaTimeModule javaTimeModule = new JavaTimeModule();
        // 设置序列化格式
        javaTimeModule.addSerializer(LocalDateTime.class,
                new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        mapper.registerModule(javaTimeModule);

        try {
            System.out.println(mapper.writeValueAsString(LocalDateTime.now()));
            // "2023-05-19 15:29:01"
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

如果确实不生效,可以临时修改单个字段的序列化方式

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "Asia/Shanghai")
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
private LocalDateTime updateTime;

自己出现的坑

由于线上生产环境还多了一个数据加密的拦截,拦截前会将数据先进行序列化,此时并没有走统一的序列化,导致线上一直提示序列化失败,而开发环境是可以的,一度认为是配置错了,或者是打包结果不对导致的

最终排查发现是数据加密拦截器中数据序列化没有走配置好的序列化方式

参考
使用Jackson JSR310模块反序列化LocalDateTime

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 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 库对于 LocalDate、LocalTime 和 LocalDateTime 类型的序列和反序列需要添加 `com.fasterxml.jackson.datatype:jackson-datatype-jsr310` 的依赖。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值