Pages

Sunday, May 17, 2020

Joda Datetime Jackson DeSerialization - @JsonDeserialize

1. Introduction


In this tutorial, You'll learn how to deserialize the Joda DateTime object when working with Jackson JSON to Object conversion java 8.

Jackson String JSON to Object

Jackson API @JsonDeserialize annotation is to use for the custom deserializer and also is to parse the dates using " com.fasterxml.jackson.databind.deser.std.StdDeserializer<DateTime>" class from to Joda API datetime to String.


Joda Datetime Jackson DeSerialization - JSON to Object @JsonDeserialize





2. Example Joda DateTime Fields with Jackson

First, let us write a simple example that tries to convert book json to Book objects using Jackson api.

Jackson JSON to Object @JsonDeserialize

Book.java


Observe the below code where it has int, String fields. And also it has DateTime of Joda API to store the book released time.


package com.javaprogramto.jackson.datetime;

import org.joda.time.DateTime;

public class Book {

    private int id;
    private String title;
    private int pages;
    private DateTime timeReleased;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getPages() {
        return pages;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }

    public DateTime getTimeReleased() {
        return timeReleased;
    }

    public void setTimeReleased(DateTime timeReleased) {
        this.timeReleased = timeReleased;
    }

    @Override    
public String toString() {
        return "Book{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", pages=" + pages +
                ", timeReleased=" + timeReleased +
                '}';
    }
}



book.json


{
  "id": "100",
  "title": "Java Program To Blog",
  "pages": "500",
  "timeReleased": "2019-11-09"}


JSON to Book Object using Jackon


package com.javaprogramto.jackson.datetime;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.io.IOException;

public class BookToString {

    public static void main(String[] args) {

        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);


        try {
            // JSON file to Java object            Book book = mapper.readValue(new File("/Users/venkateshn/Documents/VenkY/blog/workspace/CoreJava/src/main/resources/book.json"), Book.class);

            System.out.println("book object from josn : " + book);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Output:

 com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `org.joda.time.DateTime` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('2019-11-09')

 at [Source: (File); line: 5, column: 19] (through reference chain: com.javaprogramto.jackson.datetime.Book["timeReleased"])

 at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)

 at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1451)

 at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1081)

 at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:371)

 at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:323)

 at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1396)

 at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:176)

 at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:166)

 at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)

 at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:293)

 at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:156)

 at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4482)

 at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3299)

 at com.javaprogramto.jackson.datetime.BookToString.main(BookToString.java:17)


It is failed because Jackson does not know how to parse the Joda DateTime properly.

Java 8 new Date-Time API

If you remove the timeReleased field then it generates the output as expected.

[book object from josn : Book{id=100, title='Java Program To Blog', pages=500}]

3. Custom DeSerializer for Joda DateTime Fields

Altogether now, Let us build the custom deserializer to covert String to DateTime format and map to timeReleased field.

@JsonDeserialize(using = CustomDateTimeDeserializer.class)
private DateTime timeReleased;

Custom Deserializer:

Next, Use StdDeserializer interface and override deserialize() method.

package com.javaprogramto.jackson.datetime;


import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.io.IOException;

public class CustomDateTimeDeserializer extends StdDeserializer<DateTime> {
    private static final long serialVersionUID = 1L;
    private static DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd");

    public CustomDateTimeDeserializer() {
        this(null);
    }

    public CustomDateTimeDeserializer(Class<DateTime> t) {
        super(t);
    }

    @Override    public DateTime deserialize(JsonParser parser, DeserializationContext context)
            throws IOException, JsonProcessingException {

        String date = parser.getText();

        return format.parseDateTime(date);

    }
}

Output:

[book object from josn : Book{id=100, title='Java Program To Blog', pages=500, timeReleased=2019-11-09T00:00:00.000+05:30}]

4. Conclusion


In this article, You've seen how to deserialize the Joda DateTime in Jackson API.

Next, How To Increment/Decrement Date Using Java Joda DateTime?

All the code is shown in this article is over GitHub.

You can download the project directly and can run in your local without any errors.



If you have any queries please post in the comment section.

No comments:

Post a Comment

Please do not add any spam links in the comments section.