首先贴出报错信息:
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());
}
}
测试:
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