解决报错InvalidDefinitionException Java 8 date/time type LocalDateTime not supported by default jsr310

这篇具有很好参考价值的文章主要介绍了解决报错InvalidDefinitionException Java 8 date/time type LocalDateTime not supported by default jsr310。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. 报错信息

最近新开了一个测试项目,使用了Java8的LocalDateTime替换了之前使用的Date类。接口返回结果时,抛出了序列化异常:

java.lang.reflect.UndeclaredThrowableException: null
…………
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: 
add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: 
cn.xx.dao.common.Back["data"]->cn.xx.dao.data.vo.BmVo["spe"]->
cn.xx.dao.entity.Spe["createTime"])





二. 版本信息

spring boot:2.5.1
jackson-databind:2.12.3

……
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.1</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
……
<dependencies>
      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.12.3</version>
          <scope>compile</scope>
      </dependency>
</dependencies>





三. 解决方法

1. 使用@JsonSerialize + @JsonDeserialize注解
  1. pom加上这两个注解的依赖
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.12.3</version>
</dependency>
  1. 在使用LocalDateTime的属性上添加这两个序列化反序列化注解:
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime createTime;

这时序列化正常,接口返回了结果,但是很明显不是我们需要的结果:

{
	"createTime": [
		2023,
		3,
		20,
		17,
		34,
		37
	]
}
  1. 加上@JsonFormat来格式化时间,现在就可以正常输出了:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime createTime;

InvalidDefinitionException这个报错,大部分博客提供的思路都是这个,理论上没什么问题,但是实际情况可能需要全局处理如LocalDateTime的时间格式,如果为相关的时间字段一个个的加注解,又太过麻烦。所以这种方法只能用于需要处理特定时间格式的字段上。



2. 回退Spring Boot版本

鉴于方法A只能作用于局部,而使用Jackson2ObjectMapperBuilderCustomizer时,仍然无法解决InvalidDefinitionException这个异常问题,只能将Spring Boot回退至2.4.x版本,问题得到解决。
参考:Spring Boot 2.5.0 and InvalidDefinitionException: Java 8 date/time type java.time.Instant not supported by default

解决流程:

  1. 设置Jackson2ObjectMapperBuilderCustomizer:
@Configuration
public class GlobalDateConfig {
	// 序列化时设置的时间格式
	private final String formatter = "yyyy-MM-dd HH:mm:ss";
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            DateTimeFormatter localDateTimeFormatter = DateTimeFormatter.ofPattern(formatter);
            //返回时间数据序列化
            builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(localDateTimeFormatter));
            // 接收时间数据反序列化
            builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(localDateTimeFormatter));
        };
    }
}
  1. 回退Spring Boot版本至2.4.x
……
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.2</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
……
  1. 重启执行,问题解决



3. 回退jackson版本

Spring Boot 2.4.x使用的是jackson 2.11.x
Spring Boot 2.5.x使用的是jackson 2.12.x
参考:Spring Boot 2.5.0 and InvalidDefinitionException: Java 8 date/time type java.time.Instant not supported by default

  1. 无须修改Spring Boot版本,并显式的指定jackson版本(2.13也报这个错误,原因可以参考这里:a change in Jackson 2.12、comment of 2.4 and 2.5)
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.11.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.11.2</version>
</dependency>
  1. 使用上文的GlobalDateConfig配置,重启执行,问题解决





四. 一些尝试(未解决问题)

根据Spring Boot的讨论和Stack overflow的一些解决方法做了一些尝试,但是均未成功解决问题。

1. 向自定义ObjectMapper Bean中注册JavaTimeModule

我的项目中,并不存在这种自定义ObjectMapper且将其设置为全局Bean的情况。

如果存在自定义ObjectMapper Bean的情况下,需要注册处理java8时间序列化的类:JavaTimeModule(或者Jdk8Module)

@Bean
@Primary
public ObjectMapper objectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new JavaTimeModule());
    return objectMapper;
}

或者:

@Bean
@Primary
public ObjectMapper objectMapper() {
    return JsonMapper.builder()
            .addModule(new JavaTimeModule())
            .build();
}

或者

@Resource
private Jackson2ObjectMapperBuilder mapperBuilder;

@Bean
@Primary
public ObjectMapper objectMapper() {
    ObjectMapper build = mapperBuilder.build();
    objectMapper.registerModule(new JavaTimeModule());
    return objectMapper;
}

这几种情况没遇到过,不知道是否可行。总之这里对我的代码不起作用。
此外,JavaTimeModule还支持自定义格式

DateTimeFormatter localDateTimeFormatter = DateTimeFormatter.ofPattern(formatter);
// 添加Java8时间序列化反序列化
JavaTimeModule javaTimeModule = new JavaTimeModule();
//返回时间数据序列化
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(localDateTimeFormatter));
//接收时间数据反序列化
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(localDateTimeFormatter));



2. 设置Jackson2ObjectMapperBuilder类
  1. 设置Jackson2ObjectMapperBuilder类,控制序列化和反序列化操作。

很明显,这个就是实现一个Jackson2ObjectMapperBuilderCustomizer类,与上文中的方法jackson2ObjectMapperBuilderCustomizer作用相同。这里也无法解决开头的问题。

@Configuration
public class GlobalDateConfig implements Jackson2ObjectMapperBuilderCustomizer {
    private final String formatter = "yyyy-MM-dd HH:mm:ss";
    @Override
    public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
        jacksonObjectMapperBuilder.simpleDateFormat(formatter)
                .modules(new JavaTimeModule())
                .serializationInclusion(JsonInclude.Include.ALWAYS)
                .failOnEmptyBeans(false)
                .failOnUnknownProperties(false)
                .featuresToEnable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN)
                .featuresToEnable(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS);
    }
}



参考

Spring Boot 2.5.0 and InvalidDefinitionException: Java 8 date/time type java.time.Instant not supported by default
文章来源地址https://www.toymoban.com/news/detail-560938.html

到了这里,关于解决报错InvalidDefinitionException Java 8 date/time type LocalDateTime not supported by default jsr310的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 已解决JSON parse error: Cannot deserialize value of type `java.time.LocalDateTime` from String

    已解决JSON parse error: Cannot deserialize value of type java.time.LocalDateTime from String 下滑查看解决方法 JSON parse error: Cannot deserialize value of type java.time.LocalDateTime from String 这个问题通常出现在将一个字符串转换为LocalDateTime对象时。 下滑查看解决方法 解决这个问题的方法取决于你使用的

    2024年02月08日
    浏览(60)
  • Java 8 datetime type `java.time.LocalDateTime` not supported by default add Module com.fasterxml.jac

    之前的项目好好的,突然报Java 8 date/time type java.time.LocalDateTime not supported by default: add Module “com.fasterxml.jackson.datatype:jackson-datatype-jsr310” to enable handling错误, 原因是之前基本上没有涉及LocalDateTime相关的代码所有问题一直没有发现,我们使用springboot的默认的jackson序列化,也没

    2024年01月21日
    浏览(47)
  • SpringBoot报错java.time.LocalDateTime cannot be cast to java.sql.Timestamp] with root cause

    最近在做系统升级,原本的版本为 SpringBoot2.1.8RELEASE ,升级后版本为 SpringBoot2.7.0 升级后原代码报错java.time.LocalDateTime cannot be cast to java.sql.Timestamp] with root cause。 经检查,原代码部分数据使用Map接收数据库返回数据,使用Map.get()取出 Object 对象后强制转化为了 Date 类型。 升级

    2023年04月08日
    浏览(50)
  • Java8 掌握Date与Java.time转换的核心思路,轻松解决各种时间转换问题

    Java8时区时间运用详解,2万字助你通关java.time包 各种时间类的转换核心只有一个流程: 时间类 - 时间戳 - 时间类 Date和Instant它们存储的都是时间戳信息 LocalDateTime、LocalDate、LocalTime、ZonedDateTime、OffsetDateTime、OffsetTime、Year等其它Java8时间类则是 年、月、日、时、分、秒、纳秒

    2024年02月02日
    浏览(63)
  • java~Date和LocalDateTime及Instant的使用场景

    在 Java 中, LocalDateTime 、 Date 和 Instant 分别代表了不同的日期时间类型,它们之间有一些区别和适用场景。 Date : java.util.Date 是 Java 早期的日期时间类,它包含了日期和时间信息,但是在设计上存在一些问题,因此并不推荐在新的代码中使用。 Date 类存在线程安全性问题,同

    2024年02月21日
    浏览(48)
  • Java中Date、Calendar、LocalDateTime时间戳转换日期

    时间戳是指格林威治时间 1970 年 01 月 01 日 00 时 00 分 00 秒 ( 北京时间 1970 年 01 月 01 日 08 时 00 分 00 秒 ) 起至现在的总毫秒数,本质是一个long 类型的整数,表示日期对象。 以下时Java中Date、Calendar、LocalDateTime与时间戳转换日期 Date类时间戳转换日期: Calendar类时间戳转换日

    2024年02月11日
    浏览(44)
  • Java String、Date、Calendar、LocalDate和LocalDateTime互转

    目录 一、String和Date互转 1.1 String时间转为Date 1.2 Date转为String 二、String和Calendar互转 2.1 String时间转为Calendar 2.2 Calendar转为String 三、String和LocalDate(LocalDateTime)互转 3.1 String时间转为LocalDate(LocalDateTime) 3.2 LocalDate(LocalDateTime)转为String 四、Date和Calendar互转 4.1 Date转为Calen

    2024年02月06日
    浏览(48)
  • Java中LocalDateTime/DateTime与Date相互转化(java中时间转化)

    LocalDateTime是JDK1.8出现的新特性,解决线程不安全的问题,但是当前很多的相关插件或者使用较低版本的时候,会依旧使用Date的情况,这个时候就需要两者之间的相互转化 新增的API严格区分了时刻、本地日期、本地时间,并且,对日期和时间进行运算更加方便。 其次,新AP

    2024年02月15日
    浏览(44)
  • java关于后端怎么去接收Date、LocalDateTime类型的参数

    Date类型后端入参的格式默认为2019/01/18 11:11:11 Get方式传参 是 没有时区的影响的 @JsonFormat的作用: 返回给前端的时间是经过@JsonFormat格式化的时间。 @DateTimeFormat的作用: 前端需要按照@DateTimeForma的格式进行传参 示例: Date 类型直接作为参数的情况 Date类型属性的实体类作为参

    2024年02月05日
    浏览(43)
  • java中LocalDateTime、Calendar、Date三种时间类型进行加减

    介绍了三种日期类型以及他们的日期加减 什么是LocalDateTime LocalDateTime是Java 8中的一个类,表示不带时区的日期和时间。它是java.time包中的一个类,用于处理日期和时间的操作。 LocalDateTime包含日期和时间的信息,不包含时区信息。它提供了各种方法来获取和操作日期和时间的

    2024年02月04日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包