【问题标题】:How do I convert a json that contains a LocalDate field to deserializable format?如何将包含 LocalDate 字段的 json 转换为可反序列化的格式?
【发布时间】:2017-10-07 20:41:55
【问题描述】:

我有一个存储在字符串中的对象。对象的字段之一是 LocalDate。

"from": {
        "year": 1000,
        "month": "JANUARY",
        "era": "CE",
        "dayOfMonth": 1,
        "dayOfWeek": "WEDNESDAY",
        "dayOfYear": 1,
        "leapYear": false,
        "monthValue": 1,
        "chronology": {
            "calendarType": "iso8601",
            "id": "ISO"
        }
    }

我应该如何将此 json 转换为可用于反序列化的格式?

以下代码

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;


ObjectMapper om = new ObjectMapper();
om.registerModule(new JavaTimeModule());
MyCustomObject obj = om.readValue(json, MyCustomObject.class); //error

导致此异常:

com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (START_OBJECT), expected VALUE_STRING: Expected array or string.

这是我用作 MyCustomObject

的 MyCustomObject 类
public class MyCustomObject<T> {
    private T from;
    private T to;

    public MyCustomObject() {
    }

    public T getFrom() {
        return this.from;
    }

    public void setFrom(T from) {
        this.from = from;
    }

    public T getTo() {
        return this.to;
    }

    public void setTo(T to) {
        this.to = to;
    }
}

【问题讨论】:

  • 你能分享你的MyCustomObject代码吗?

标签: java json java-8 jackson jsr310


【解决方案1】:

像这样替换您的 MyCustomObject.class:

==================================
package ;
public class Chronology
{
    private String calendarType;

    private String id;

    public void setCalendarType(String calendarType){
        this.calendarType = calendarType;
    }
    public String getCalendarType(){
        return this.calendarType;
    }
    public void setId(String id){
        this.id = id;
    }
    public String getId(){
        return this.id;
    }
}

==================================
package ;
public class From
{
    private int year;

    private String month;

    private String era;

    private int dayOfMonth;

    private String dayOfWeek;

    private int dayOfYear;

    private boolean leapYear;

    private int monthValue;

    private Chronology chronology;

    public void setYear(int year){
        this.year = year;
    }
    public int getYear(){
        return this.year;
    }
    public void setMonth(String month){
        this.month = month;
    }
    public String getMonth(){
        return this.month;
    }
    public void setEra(String era){
        this.era = era;
    }
    public String getEra(){
        return this.era;
    }
    public void setDayOfMonth(int dayOfMonth){
        this.dayOfMonth = dayOfMonth;
    }
    public int getDayOfMonth(){
        return this.dayOfMonth;
    }
    public void setDayOfWeek(String dayOfWeek){
        this.dayOfWeek = dayOfWeek;
    }
    public String getDayOfWeek(){
        return this.dayOfWeek;
    }
    public void setDayOfYear(int dayOfYear){
        this.dayOfYear = dayOfYear;
    }
    public int getDayOfYear(){
        return this.dayOfYear;
    }
    public void setLeapYear(boolean leapYear){
        this.leapYear = leapYear;
    }
    public boolean getLeapYear(){
        return this.leapYear;
    }
    public void setMonthValue(int monthValue){
        this.monthValue = monthValue;
    }
    public int getMonthValue(){
        return this.monthValue;
    }
    public void setChronology(Chronology chronology){
        this.chronology = chronology;
    }
    public Chronology getChronology(){
        return this.chronology;
    }
}

==================================
package ;
public class MyCustomObject
{
    private From from;

    public void setFrom(From from){
        this.from = from;
    }
    public From getFrom(){
        return this.from;
    }
}

【讨论】:

    【解决方案2】:

    LocalDate 错误地存储在 JSON 中。

    解决问题的正确方法是确保生成 JSON 的ObjectMapper 已注册JavaTimeModuleJdk8Module。这可确保LocalDate 正确序列化为[year, month, day] 的JSON 数组。

    蛮力方法是遵循@Roy 在另一个答案中概述的解决方案,并将每个相关字段手动转换为LocalDate。类似于:

    LocalDate date = LocalDate.now()
            .with(ChronoField.YEAR, year)
            .with(ChronoField.MONTH_OF_YEAR, Month.valueOf(month).getValue())
            .with(ChronoField.DAY_OF_MONTH, dayOfMonth);
    

    这显然很容易出错,而不是这些类的预期使用方式。

    【讨论】:

      猜你喜欢
      • 2021-12-06
      • 2018-09-28
      • 2021-07-17
      • 1970-01-01
      • 1970-01-01
      • 2018-09-15
      • 1970-01-01
      • 2018-12-13
      相关资源
      最近更新 更多