为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

郎朗坤 2022-06-15 15:21:05
我有两个通过 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 让它工作?
查看完整描述

2 回答

?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

我记得旧版本的spring没有这个问题(或者我很幸运)但这就是我在Spring boot 2.1.7.RELEASE中解决它的方法:


首先,添加Jackson 的支持模块以支持 Java 8 功能(TimeDate API)


    <dependency>

        <groupId>com.fasterxml.jackson.module</groupId>

        <artifactId>jackson-module-parameter-names</artifactId>

    </dependency>

    <dependency>

        <groupId>com.fasterxml.jackson.datatype</groupId>

        <artifactId>jackson-datatype-jdk8</artifactId>

    </dependency>

    <dependency>

        <groupId>com.fasterxml.jackson.datatype</groupId>

        <artifactId>jackson-datatype-jsr310</artifactId>

    </dependency>

然后在 Spring 中注册一个带有自定义配置(以支持 Java 8)的默认 ObjectMapper bean。


@Bean

@Primary

public ObjectMapper geObjMapper(){

    return new ObjectMapper()

            .registerModule(new ParameterNamesModule())

            .registerModule(new Jdk8Module())

            .registerModule(new JavaTimeModule());

}

注意:@Primary 用作预防措施,因此如果类路径上有其他 ObjectsMapper bean,spring 将默认选择这个。


查看完整回答
反对 回复 2022-06-15
?
慕容708150

TA贡献1831条经验 获得超4个赞

您编写的解决方案是正确的方法。其他方法如下所述。公共类 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>

{

    @Override

    public Date deserialize(JsonParser jsonParser,

            DeserializationContext deserializationContext) throws IOException, JsonProcessingException {


        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

        String date = jsonParser.getText();

        try {

            return format.parse(date);

        } catch (ParseException e) {

            throw new RuntimeException(e);

        }


    }


}


@JsonDeserialize(using = CustomJsonDateDeserializer.class)


查看完整回答
反对 回复 2022-06-15
  • 2 回答
  • 0 关注
  • 859 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号