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