Jackson解析json字符串时报错:Cannot construct instance of `java.time.OffsetDateTime`的解决方案


首先贴出报错信息:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.OffsetDateTime` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('2018-01-01T12:05:14Z')
 at [Source: (String)"{"header":{"id":"7fdf40b1-5d98-4d83-9aaa-e6e7422c9f44",...,"creation_date_time":"2018-01-01T12:05:14Z"}"; line: 1, column: 77] (through reference chain: org.openmhealth.schema.domain.omh.DataPoint["header"]->org.openmhealth.schema.domain.omh.DataPointHeader["creation_date_time"])

简单看一下报错的信息大概就是Jackson在构建一个java.time.OffsetDateTime的实体时失败了,没有这样的一个构造器。也就是说对于这样一个字段2018-01-01T12:05:14Z不能将其还原成java.time.OffsetDateTime的一个对象。

了解出错的原因之后,我们再来看看如何将这个问题解决。

查阅资料后了解到,其实com.fasterxml.jackson.datatype: jackson-datatype-jsr310这个库提供了java.time.OffsetDateTime的解析支持,并且实现解析的方法也很简单,只需要对Jackson的ObjectMapper对象注册一个JavaTimeModule()就好了。

具体代码如下:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());

好了,这样你的Jackson就能解析java.time.OffsetDateTime类型的字符串了。
除此之外,jackson-datatype-jsr310还支持以下几种数据类型:

  • Duration
  • Instant
  • LocalDateTime
  • LocalDate
  • LocalTime
  • MonthDay
  • OffsetDateTime
  • OffsetTime
  • Period
  • Year
  • YearMonth
  • ZonedDateTime
  • ZoneId
  • ZoneOffset

简单实验:

测试代码如下:(测试代码都略去了import部分,只包含程序主体)

Order类:

public class Order {
    private OffsetDateTime orderTime;
    private Long id;

    public OffsetDateTime getOrderTime() {
        return orderTime;
    }

    public void setOrderTime(OffsetDateTime orderTime) {
        this.orderTime = orderTime;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Order{" +
                "orderTime=" + orderTime +
                ", id=" + id +
                '}';
    }
}

JsonParser定义如下:

public class JsonParser {

    public void parseJson() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonString = "[{\"orderTime\":\"2018-01-01T12:05:14Z\", \"id\":201801011205}]";
        JavaType type = TypeFactory.defaultInstance().constructType(Order.class);
        Order order = objectMapper.readValue(jsonString, type);
        System.out.println("解析json字符串之后得到的是: "+order.toString());
    }

}

json可视化工具

测试:

JsonParser jsonParser = new JsonParser();
jsonParser.parseJson();

程序报错,报错信息即为无法正常构建。

JsonParser做少许改造,使其能够正常解析java.time.OffsetDateTime的字符串。

public class JsonParser {
    
    public void parseJson() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        //下面这行代码使得objectMapper支持解析java.time.OffsetDateTime
        objectMapper.registerModule(new JavaTimeModule());
        String jsonString = "[{\"orderTime\":\"2018-01-01T12:05:14Z\", \"id\":201801011205}]";
        JavaType type = TypeFactory.defaultInstance().constructType(Order.class);
        Order order = objectMapper.readValue(jsonString, type);
        System.out.println("解析json字符串之后得到的是: "+order.toString());
    }
}

运行结果如下:

解析json字符串之后得到的是: Order{orderTime=2018-01-01T12:05:14Z, id=201801011205}

Jackson解析java.time.OffsetDateTime成功!



参考资料:
serialize/deserialize java 8 java.time with Jackson JSON mapper


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM