首先貼出報錯信息:
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