Home > Mobile >  How to deserialize JSON containing LocalDate field generated by GSON library
How to deserialize JSON containing LocalDate field generated by GSON library

Time:10-20

I have JSON string which was generated by GSON library and it looks like :

{
    "id": 10,
    "articleNumber": 5009,
    "processDate": {
      "year": 2021,
      "month": 1,
      "day": 1
    },
    "price": 1.22
}

I want to use Jackson for deserialize the above JSON. But it fails at processDate field due to the format how processDate field is present in the JSON.

How to parse the above JSON string by using some custom deserializer?

CodePudding user response:

It seems you unwillingly got Jackson's built-in LocalDateDeserializer parsing your date. This deserializer supports several JSON date formats (string, integer array, epoch day count)

  • "2021-1-1"
  • [2021, 1, 1]
  • 18627

but unfortunately not your object-like format

  • { "year": 2021, "month" :1, "day": 1 }

Therefore you need to write your own deserializer for LocalDate. This is not so hard.

public class LocalDateDeserializer extends JsonDeserializer<LocalDate> {

    @Override
    public LocalDate deserialize(JsonParser parser, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        JsonNode node = parser.getCodec().readTree(parser);
        try {
            int year = ((IntNode) node.get("year")).intValue();
            int month = ((IntNode) node.get("month")).intValue();
            int day = ((IntNode) node.get("day")).intValue();
            return LocalDate.of(year, month, day);
        } catch (Exception e) {
            throw JsonMappingException.from(parser, node.toString(), e);
        }
    }
}

Then, in your Java class you need to tell Jackson, that you want its processDate property be deserialized by your own LocalDateDeserializer.

public class Root {

    private int id;

    private int articleNumber;

    @JsonDeserialize(using = LocalDateDeserializer.class)
    private LocalDate processDate;

    private double price;
    
    // getters and setters (omitted here for brevity)
}

CodePudding user response:

I dont know java that well, just make a custom type like this. below just create a custom Struct like:

inline class processDate {
    int year,
    int month,
    int day,
    public Date getDate(){
        DateFormat formatter = new SimpleDateFormat("dd-MMM-yy");
        Date date = formatter.parse(this.day   "-"   this.month   "-"   this.year);
        return date;
    }

}
  • Related