Main Tutorials

Jackson Java 8 date/time type `java.time.LocalDate` not supported by default

This article shows how Jackson can support the Java 8 date time APIs or JSR-310.

Table of contents:

P.S Tested with Jackson 2.17.0

1. Download Jackson

Declares jackson-databind at pom.xml.

pom.xml

  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.17.0</version>
  </dependency>

2. Jackson does not support Java 8 date time APIs

The following example demonstrates the use of Jackson to convert a Java object, Book, that has a field containing the Java 8 time APIs, like LocalDate, to a JSON formatted string.

Book.java

import java.math.BigDecimal;
import java.time.LocalDate;

public class Book {

  private Long id;
  private String title;
  private BigDecimal price;

  // Java 8 date time APIs 
  private LocalDate publishDate;

  // getters, setters and constructors
}

By default, Jackson will throw the error "Java 8 date/time type java.time.LocalDate not supported by default" if the Java object contains Java 8 date/time APIs.

JacksonJava8TimeExample.java

  ObjectMapper om = new ObjectMapper();

  Book book =
          new Book(1L, "Book A",
                  BigDecimal.valueOf(9.99),
                  LocalDate.of(2023, 10, 1));

  // convert object to json
  String result = om.writeValueAsString(book);
Terminal

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
  Java 8 date/time type `java.time.LocalDate` not supported by default:
  add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
  (through reference chain: com.mkyong.json.model.Book["publishDate"])
  at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
  at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1308)
  at com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer.serialize(UnsupportedTypeSerializer.java:35)
  at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:732)
  at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:772)
  at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
  at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:479)
  at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:318)
  at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1572)
  at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1273)
  at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1140)
  at com.mkyong.json.jackson.Java8TimeApiSupportApp.main(Java8TimeApiSupportApp.java:22)

3. Make Jackson support Java 8 date time APIs or JSR310

We must manually add the dependency jackson-datatype-jsr310 and register the JavaTimeModule() to make Jackson support Java 8 date time APIs.

3.1 jackson-datatype-jsr310

pom.xml

  <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.17.0</version>
  </dependency>

  <!-- support for "Java 8 date time api" -->
  <dependency>
      <groupId>com.fasterxml.jackson.datatype</groupId>
      <artifactId>jackson-datatype-jsr310</artifactId>
      <version>2.17.0</version>
  </dependency>

3.1 Register JavaTimeModule()

A Book object has a field containing Java 8 date api LocalDate.

Book.java

import java.math.BigDecimal;
import java.time.LocalDate;

public class Book {

  private Long id;
  private String title;
  private BigDecimal price;

  // Java 8 date time APIs 
  private LocalDate publishDate;

  // getters, setters and constructors
}

Here, we manually register the JavaTimeModule() to make Jackson support Java 8 date time APIs.

JacksonJava8TimeExample.java

package com.mkyong.json.jackson;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.mkyong.json.model.Book;

import java.math.BigDecimal;
import java.time.LocalDate;

public class JacksonJava8TimeExample {

    public static void main(String[] args) throws JsonProcessingException {

        ObjectMapper om = new ObjectMapper();

        // support Java 8 date time apis
        om.registerModule(new JavaTimeModule());

        // or like this
        // om.findAndRegisterModules();

        Book book =
                new Book(1L, "Book A",
                        BigDecimal.valueOf(9.99),
                        LocalDate.of(2023, 10, 1));

        // pretty print enabled
        // convert java object to json
        String result = om
                .writerWithDefaultPrettyPrinter()
                .writeValueAsString(book);

        System.out.println(result);

        // convert json to java object
        Book newBook = om.readValue(result, Book.class);
        System.out.println(newBook);


    }

}

Output


{
  "id" : 1,
  "title" : "Book A",
  "price" : 9.99,
  "publishDate" : [ 2023, 10, 1 ]
}
Book{id=1, title='Book A', price=9.99, publishDate=2023-10-01}

4. Download Source Code

5. References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments