首页 > 编程语言 >【常见问题】Java 8 date time type `java.time.LocalDateTime` not supported by default 日期序列化问题

【常见问题】Java 8 date time type `java.time.LocalDateTime` not supported by default 日期序列化问题

时间:2024-02-17 09:01:36浏览次数:29  
标签:常见问题 jackson time LocalDateTime import 序列化 com fasterxml

问题描述

将一个包含LocalDateTime对象的集合进行序列化和反序列化时,可能会遇到以下异常:

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
Java 8 date/time type `java.time.LocalDate` not supported by default: add Module 
"com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: java.util.HashMap["data"])

这是因为Jackson库在默认情况下不支持LocalDateTime类型的序列化和反序列化。为了解决这个问题,我们需要自定义序列化和反序列化的行为。

解决方案一

1. 引入依赖

            <dependency>
                <groupId>com.fasterxml.jackson</groupId>
                <artifactId>jackson-datatype-jsr310</artifactId>
                <version>${jackson.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

2. 设定时间模块

        ObjectMapper objectMapper = new CustomObjectMapper();
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"));
        objectMapper.registerModule(new JavaTimeModule());
        Map<String, Object> map = new HashMap<>();
        map.put("time", LocalDateTime.now());
        map.put("data", LocalDate.now());
        objectMapper.writeValueAsString(map);

解决方案二

1. 自定义序列化器

首先,我们需要创建一个自定义的序列化器,用于处理LocalDateTime类型的序列化和反序列化。具体实现如下:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.time.LocalDateTime;

public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
    @Override
    public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeString(value.toString());
    }
}

在这个自定义序列化器中,我们将LocalDateTime对象转换为字符串,然后使用gen.writeString()方法将其写入JSON输出流。

接下来,我们需要将这个自定义序列化器应用到我们的实体类上。假设我们有一个名为Event的实体类,其中包含一个LocalDateTime类型的属性eventTime

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.time.LocalDateTime;

public class Event {
    private String name;
    private LocalDateTime eventTime;

    // getter and setter methods ...

    @JsonSerialize(using = LocalDateTimeSerializer.class)
    public LocalDateTime getEventTime() {
        return eventTime;
    }

    public void setEventTime(LocalDateTime eventTime) {
        this.eventTime = eventTime;
    }
}

通过在getEventTime()方法上添加@JsonSerialize注解,并指定我们刚刚创建的自定义序列化器(Using = LocalDateTimeSerializer.class),我们可以确保在序列化和反序列化eventTime属性时,会使用我们定义的自定义序列化器。

2. 自定义反序列化器(可选)

如果我们希望在反序列化时保留LocalDateTime对象的类型信息,我们可以创建一个自定义的反序列化器。具体实现如下:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
    private static final DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
    private static final LocalDateTime minValue = LocalDateTime.MIN;
    private static final LocalDateTime maxValue = LocalDateTime.MAX;
    private static final long serialVersionUID = 1L; // Add a unique ID to the deserializer if needed

    @Override
    public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String value = p.getText();
        return LocalDateTime.parse(value, formatter); // Use the same formatter as in the serializer for consistency
    }
}

标签:常见问题,jackson,time,LocalDateTime,import,序列化,com,fasterxml
From: https://www.cnblogs.com/bigleft/p/18017704

相关文章

  • jackson序列化问题
    在对对象进行jackson序列化的时候,有时候会出现序列化后的变量名称大小写错误的情况。测试的实体类TestEntity2如下:public class TestEntity2 {    private String aBcd;    private String qWER;    private String qWERty;    private String qWERty......
  • 使用TimeZoneInfo代替TimeZone
    概念时间戳时间戳就是当前时间距离1970年1月1日0点0时0分0秒(转换成北京时间是1970年1月1日8点0时0分0秒)距离你要计算的时间的秒数或者毫秒数。总结:TimeZone.CurrentTimeZone.ToLocalTime(newDateTime(1970,1,1));被TimeZoneInfo.ConvertTime(newDateTime(1970,1,1),T......
  • 成功实现FaceTime语音,FaceTime视频,FaceTime数据筛选,检测手机号是否开通FaceTime的
    FaceTime是苹果公司iOS和macOS(以前称MacOSX或OSX)内置的一款视频通话软件,通过Wi-Fi或者蜂窝数据接入互联网,在两个装有FaceTime的设备之间实现视频通话。其要求通话双方均具有装有FaceTime的苹果设备,苹果ID以及可接入互联网的3G/4G/5G或者Wi-Fi网络。 一、Windows电脑上部署苹......
  • PHP项目&变量覆盖&反序列化&未授权访问&身份验证
    CNVD拿1day-验证&未授权-xhcms&Bosscms此种漏洞由于没有什么关键函数,所以需要通过功能点去进行测试。Bosscms未授权访问CNVD官网上搜索Bosscms未授权访问漏洞。根据描述,影响的是1.0版本。看到发送时间为21年12月29好,收录时间为22年1月18号。再去官网看版本更新的时间点,V1.0版......
  • LocalDateTime判断时间段归属
    //v2024-02-0207:52:572024-02-0214:39:14//DateinTime=Date.from(Instant.ofEpochMilli(1707150614000L));//LocalDateTimeinTimeLocalDateTime=DateUtil.dateToLocalDateTime(inTime);LocalDateTimeinTime=LocalDateTime.parse("2024-02-01......
  • golang定时器之timer+ticker
    转载: https://juejin.cn/post/7327157426298011663 Timer是一个一次性的定时器,用于在未来的某一时刻执行一次操作。基本使用创建Timer定时器的方式有两种:NewTimer(dDuration)*Timer:该函数接受一个time.Duration类型的参数d(时间间隔),表示定时器在过期之前等待的......
  • C#的timespan怎么使用
    https://www.yisu.com/ask/23316568.html1、TimeSpan类是用来表示时间间隔的,它提供了一些方法和属性来操作和获取时间间隔的信息。以下是一些常用的TimeSpan的用法示例:创建一个TimeSpan实例:TimeSpantimeSpan1=newTimeSpan(2,30,0);//2小时30分钟0秒TimeSpantim......
  • pandas.to_datetime datetime.combine 拼接日期时间
    在Python中,如果你想要使用datetime.date对象拼接时间,你需要先将datetime.date对象转换为datetime.datetime对象,然后再添加时间。(不转化也可以啊)importpandasaspdimportdatetimedefmain():date=pd.Timestamp.today().date()#将pd.Timestamp转为datetime.date类......
  • 使用IDEA直接连接数据库报错:Server returns invalid timezone. Go to 'Advanced' tab
    错误详情:使用IDEA直接连接数据库报错:Serverreturnsinvalidtimezone.Goto'Advanced'tabandset'serverTimezone'propertymanually.错误原因:MySQL驱动中默认时区是UTC,与本地时间有时差。解决方案:点开最右侧导航栏Advanced,找到serverTimezone,在value处填写GMT保存再......
  • datetime.date + datetime.timedelta 结果仍然是 datetime.date 因而不能与时间进行比
    importpandasaspdimportdatetimedefmain():foo=pd.Timestamp.now()bar=datetime.date.today()+datetime.timedelta(days=-1)res=bar+datetime.timedelta(hours=24)print(res,type(res))if__name__=='__main__':ma......