Search code examples
javajsonjacksondeserializationjson-deserialization

How to parse Input Object Date fields with format given in the object field itself


I have a Spring project where in the controller method I have @RequestBody Object obj as one of the parameters. Object have Date fields which with custom JSON Serializer and custom JSON Deserializer implemented using @JsonDeserializer and @JsonSerializer and the two classes.

When I send request to the controller method Spring calls the Jacksons deserialiser and deserialise string date field of Object into Date.

When deserialiser deserialise the date string and return the Date object I want it parse the string according to the format given in the Object's format field(i.e format is also given in the input) and create the Date object accordingly. How can this be implemented?

class MyObject{
    private String format; //field containing the format
    private Date currentDate;// this field should get formatted according to the 'format' field value

    @JsonSerialize(using = CustomJSONSerializer.class)
    public Date getCurrentDate(){
        return this.currentDate;
    }

    @JsonDeserialize(using = CustomJsonDeserializer.class)
    public void setCurrentDate(Date currentDate){
        this.currentDate=currentDate;
    }
}


class CustomJsonDeserializer extends JsonDeserializer<Date> {
    @Override
    public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
    //this format I want it to receive from the input as well i.e from the Object's format named instance variable.
    final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
    try {
        return simpleDateFormat.parse(jp.getText());
    } catch (ParseException e) {
        //catch exception
    }
}

Can we use JsonParser or the DeserializationContext for solving this problem?


Solution

  • You need to implement deserialiser/serialiser for whole MyObject class to have access to all required fields. See below example:

    public class MyObjectJsonDeserializer extends JsonDeserializer<MyObject> {
        @Override
        public MyObject deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            ObjectNode root = p.readValueAsTree();
            String format = root.get("format").asText();
    
            MyObject result = new MyObject();
            result.setFormat(format);
    
            SimpleDateFormat dateFormat = new SimpleDateFormat(format);
            try {
                result.setCurrentDate(dateFormat.parse(root.get("currentDate").asText()));
            } catch (ParseException e) {
                throw new JsonParseException(p, e.getMessage(), e);
            }
    
            return result;
        }
    }
    

    You can use it:

    @JsonDeserialize(using = MyObjectJsonDeserializer.class)
    public class MyObject {
    

    Similarly, you can implement and register serialiser.