无法构造 java.time.LocalDateTime 的实例 - Jackson

我有两个通过 JMS 消息传递和 ActiveMQ 进行通信的 Spring Boot 应用程序。


一个应用程序向另一个应用程序发送一个包含 LocalDateTime 属性的对象。该对象被序列化为 JSON,以便发送到其他应用程序。


我面临的问题是杰克逊在尝试将传入的 json 映射到我的对象时无法反序列化 LocalDateTime 属性。LocalDateTime 属性在到达“侦听器应用程序”时具有以下格式:


"lastSeen":{

  "nano":0,

  "year":2019,

  "monthValue":4,

  "dayOfMonth":8,

  "hour":15,

  "minute":6,

  "second":0,

  "month":"APRIL",

  "dayOfWeek":"MONDAY",

  "dayOfYear":98,

  "chronology":{

    "id":"ISO",

    "calendarType":"iso8601"

  }

}

我得到的例外如下:


org.springframework.jms.support.converter.MessageConversionException: Failed to convert JSON message content; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of java.time.LocalDateTime


我可以通过使用以下注释暂时解决此问题:


@JsonSerialize(as = LocalDateTimeSerializer.class)

@JsonDeserialize(using = LocalDateTimeDeserializer.class, as = LocalDateTime.class)

private LocalDateTime lastSeen;

但它们属于杰克逊数据类型 jsr310现在已弃用。


是否有任何方法/替代方法可以在不使用上述注释的情况下反序列化此 LocalDateTime 属性?或者我如何使用推荐的jackson-modules-java8 让它工作?


郎朗坤
浏览 860回答 2
2回答

qq_花开花谢_0

我记得旧版本的spring没有这个问题(或者我很幸运)但这就是我在Spring boot 2.1.7.RELEASE中解决它的方法:首先,添加Jackson 的支持模块以支持 Java 8 功能(TimeDate API)&nbsp; &nbsp; <dependency>&nbsp; &nbsp; &nbsp; &nbsp; <groupId>com.fasterxml.jackson.module</groupId>&nbsp; &nbsp; &nbsp; &nbsp; <artifactId>jackson-module-parameter-names</artifactId>&nbsp; &nbsp; </dependency>&nbsp; &nbsp; <dependency>&nbsp; &nbsp; &nbsp; &nbsp; <groupId>com.fasterxml.jackson.datatype</groupId>&nbsp; &nbsp; &nbsp; &nbsp; <artifactId>jackson-datatype-jdk8</artifactId>&nbsp; &nbsp; </dependency>&nbsp; &nbsp; <dependency>&nbsp; &nbsp; &nbsp; &nbsp; <groupId>com.fasterxml.jackson.datatype</groupId>&nbsp; &nbsp; &nbsp; &nbsp; <artifactId>jackson-datatype-jsr310</artifactId>&nbsp; &nbsp; </dependency>然后在 Spring 中注册一个带有自定义配置(以支持 Java 8)的默认 ObjectMapper bean。@Bean@Primarypublic ObjectMapper geObjMapper(){&nbsp; &nbsp; return new ObjectMapper()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .registerModule(new ParameterNamesModule())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .registerModule(new Jdk8Module())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .registerModule(new JavaTimeModule());}注意:@Primary 用作预防措施,因此如果类路径上有其他 ObjectsMapper bean,spring 将默认选择这个。

慕容708150

您编写的解决方案是正确的方法。其他方法如下所述。公共类 LocalDateTimeSerializer 实现 JsonSerializer { @Override public JsonElement serialize(LocalDateTime localDateTime, Type type, JsonSerializationContext jsonSerializationContext) { Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant(); 日期日期 = Date.from(instant); 返回新的 JsonPrimitive(date.getTime()); } }GsonBuilder gsonBuilder = new GsonBuilder();gsonBuilder.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer());Gson gson = gsonBuilder.create();另一种方法。无论如何试试这个。尝试将日期时间格式更改为字符串。“2011-04-08T09:00:00”。nano 和其他格式非常复杂,我无法从你 lastseen json 中看出你到底在说什么日期时间。它也错过了时区,因此您的本地时间可以在您部署解决方案的任何地方,如果您在 3 个不同的时区机器上部署本地时间是不正确的。使用此字符串格式或制作您自己的“2011-04-08T09:00:00”public class CustomJsonDateDeserializer extends JsonDeserializer<Date>{&nbsp; &nbsp; @Override&nbsp; &nbsp; public Date deserialize(JsonParser jsonParser,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DeserializationContext deserializationContext) throws IOException, JsonProcessingException {&nbsp; &nbsp; &nbsp; &nbsp; SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");&nbsp; &nbsp; &nbsp; &nbsp; String date = jsonParser.getText();&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return format.parse(date);&nbsp; &nbsp; &nbsp; &nbsp; } catch (ParseException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new RuntimeException(e);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}@JsonDeserialize(using = CustomJsonDateDeserializer.class)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java