I have a simple application with Spring Boot and Jetty. I have a simple controller returning an object which has a Java 8 ZonedDateTime
:
public clas
If you either don't rely on SpringBoot's auto-configuration feature - you don't provide spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false
property into your configuration file - or for whatever reason you create ObjectMapper
instance manually. You can disable this feature programatically as follows:
ObjectMapper m = new ObjectMapper();
m.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
this is for jackson 2.8.7
For Jackson 2.10
and above,
parent pom.xml
<!-- https://github.com/FasterXML/jackson-bom -->
<dependencyManagement>
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>2.10.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencyManagement>
module pom.xml
<!-- https://github.com/FasterXML/jackson-modules-java8 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
JsonMapper creation, possibly in your @Configuration
class
@Bean
public JsonMapper jsonMapper() {
return JsonMapper.builder()
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.addModule(new JavaTimeModule())
.build();
}
Further reading:
There is a library jackson-datatype-jsr310. Try it.
This library covers new datetime API and includes serializers for ZonedDateTime
too.
All you need is just to add JavaTimeModule
:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
UPDATE
To convert datetime to ISO-8601 string you should disable WRITE_DATES_AS_TIMESTAMPS feature. You can easily do by either overriding ObjectMapper
bean or by using application properties:
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false
The answer was already mentioned above but I think it's missing some info. For those looking to parse Java 8 timestamps in many forms (not just ZonedDateTime). You need a recent version of jackson-datatype-jsr310
in your POM and have the following module registered:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
To test this code
@Test
void testSeliarization() throws IOException {
String expectedJson = "{\"parseDate\":\"2018-12-04T18:47:38.927Z\"}";
MyPojo pojo = new MyPojo(ZonedDateTime.parse("2018-12-04T18:47:38.927Z"));
// serialization
assertThat(objectMapper.writeValueAsString(pojo)).isEqualTo(expectedJson);
// deserialization
assertThat(objectMapper.readValue(expectedJson, MyPojo.class)).isEqualTo(pojo);
}
Note that you can configure your object mapper globally in Spring or dropwizard to achieve this. I have not yet found a clean way to do this as an annotation on a field without registering a custom (de)serializer.