首页 > 解决方案 > 杰克逊的 InvalidDefinitionException

问题描述

在 Spring Boot 2.2.2 中,Java 11 通过 Ibm mq 接收到一个对象。

收到的对象具有 LocalDate 数据类型。

项目在 Maven 中有 spring-boot-starter-web 启动器。

我在项目中看到了这些 jar

杰克逊数据类型-jdk 8-2.10.1 杰克逊数据类型-jsr310-2.10.1

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class BillingEvent {
    public Long Id;
    public LocalDate billingCreatedDate;
}

在我的财产中,我有

spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false

我得到的错误

com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造实例java.time.LocalDate(没有创建者,如默认构造,存在):没有从字符串值反序列化的字符串参数构造函数/工厂方法('2019-09-02')

标签: javaspring-bootjacksondeserializationlocaldate

解决方案


对我来说,将 setter 添加到您的 中就足够了BillingEvent,例如:

public void setBillingCreatedDate(String str) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");        
    billingCreatedDate = LocalDate.parse(str, formatter);
}

有关格式化的更多信息:String to LocalDate

根据评论:

是JDK8 java.time的杰克逊数据类型模块吗?可能对您有所帮助,如果没有帮助,请参考以下工作 impl 示例。(没有任何检查左右):

public class LocalDateDeserializer extends JsonDeserializer<LocalDate> {

    private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    @Override
    public LocalDate deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {        
          return LocalDate.parse(p.readValueAs(String.class), formatter);
    }

}

您也可以在其他地方使用它,就像在您的BillingEvent

@JsonDeserialize(using = LocalDateDeserializer.class)
public LocalDate billingCreatedDate;

推荐阅读