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:
- 1. Download Jackson
- 2. Jackson does not support Java 8 date time APIs
- 3. Make Jackson support Java 8 date time APIs or JSR310
- 4. Download Source Code
- 5. References
P.S Tested with Jackson 2.17.0
1. Download Jackson
Declares jackson-databind
at 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.
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.
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);
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
<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
.
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.
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
$ git clone https://github.com/mkyong/java-json