4

I have an object stored in a String. One of the object's fields is a LocalDate.

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

How should I go about converting this json to a format that can be used for deserializing it?

The following code

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

causes this Exception:

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

Here's the MyCustomObject class which I use as MyCustomObject<LocalDate>

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;
    }
}
naglas
  • 462
  • 1
  • 6
  • 16

2 Answers2

1

Replace your MyCustomObject.class like this:

==================================
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;
    }
}
Avinash Roy
  • 953
  • 1
  • 8
  • 25
0

The LocalDate is stored in incorrectly in the JSON.

The correct way to fix the problem is to ensure that the ObjectMapper generating the JSON has the JavaTimeModule or the Jdk8Module registered. This ensures that the LocalDate is correctly serialized to a JSON array of [year, month, day].

The brute-force method is to follow the solution that @Roy outlined in another answer, and convert each relevant field manually to a LocalDate. Something along the lines of :

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

This is obviously rather error-prone, and not how the classes were intended to be used.

Henrik Aasted Sørensen
  • 6,966
  • 11
  • 51
  • 60