I'm working on converting some models in a spring-boot REST API app to use java 8's java.time.LocalDateTime
instead of joda's DateTime
. I want the timestamps returned from API call to adhere to the ISO_8601
format. Motivation is to be forward compatible with Java 8's time (more here).
The part that's proving difficult is when it comes to serialize an object containing LocalDateTime
to JSON.
For example, I have the following entity:
// ... misc imports
import java.time.LocalDateTime;
import java.time.ZoneOffset;
@Data
@Entity
@Table(name = "users")
public class User {
@Id @Column
private String id;
@Column
private String name;
@Column
private String email;
@Column
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "UTC")
private java.time.LocalDateTime createdAt;
public User(String name, String email) {
this.id = Utils.generateUUID();
this.createdAt = LocalDateTime.now(ZoneOffset.UTC);
}
}
I have also set my application.properties
to turn off the dates as timestamp jackson feature:
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false
My maven deps:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.1.Final</version>
</dependency>
Finally, I try to retrieve the JSON representation via controller:
@RequestMapping("/users")
@RestController
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping(
value = "/{id}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE
)
public User getUser(@PathVariable("id") String id) {
return userService.findById(id);
}
}
When I actually make a call to this endpoint, I get the following exception:
java.lang.NoSuchMethodError:
com.fasterxml.jackson.datatype.jsr310.ser.JSR310FormattedSerializerBase.findFormatOverrides(Lcom/fasterxml/jackson/databind/SerializerProvider;Lcom/fasterxml/jackson/databind/BeanProperty;Ljava/lang/Class;)Lcom/fasterxml/jackson/annotation/JsonFormat$Value;
Alternately I also configured the app's ObjectMapper
in the configuration class:
@Configuration
public class ServiceConfiguration {
@Bean
public ObjectMapper getJacksonObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(
com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
false
);
return objectMapper;
}
}
Any leads will be greatly appreciated.
UPDATE:
Turns out it was a version mismatch between Spring Boot's Jackson version and the one I had in my pom.xml
. As Miloš and Andy proposed, once I've set the correct version and run the app with spring.jackson.serialization.write_dates_as_timestamps=true
, the issue was resolved, without needing to configure the ObjectMapper
or adding annotations on my LocalDateTime
model fields.
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.3.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
</dependencies>