When I tried to convert special data types like LocalDateTime into JSON I ran against a wall. It took me hours to find the solution. If you face the same problem, here is the solution:
pom.xml
The first thing you need are the libraries that contain the neccessary converters:
<!-- Jackson --> <dependency> <!-- Java 8 Parameter names --> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-parameter-names</artifactId> </dependency> <dependency> <!-- Java 8 Optional --> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jdk8</artifactId> </dependency> <dependency> <!-- Java 8 LocalDate/Time --> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.8.8</version> </dependency> <dependency> <!-- Kotlin class and data classes without default constructor --> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-kotlin</artifactId> <version>2.8.8</version> </dependency>
For our problem with LocalDateTime only jackson-datatype-jsr310
is important. But with jackson-module-parameter-names
you get the Java 8 feature of accessing parameter names without annotating them. jackson-datatype-jdk8
offers you the possibility to use e.g. Optional for a JSON interface. And last but not least jackson-module-kotlin
add the power of Kotlin constructors to JSON converters.
Configuration
As often, I use Spring as a base for my development. So I need a configuration that tells Spring to add the afore mentioned modules to the ObjectMapper of Jackson. This is done by the following code snippet:
@Bean fun objectMapper(): ObjectMapper = ObjectMapper() .registerModule(JavaTimeModule()) .registerModule(ParameterNamesModule()) .registerModule(Jdk8Module()) .registerModule(KotlinModule())
As you can see, this is Kotlin code that perfectly integrates into your Spring application.
Usage in the DTO
My DTO class now can use any format definition for the JSON output of the date:
@get:JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd.MM.yyyy hh:mm:ss") val changeTime: LocalDateTime? = null,
This a common german style of displaying a local date and time. It could look like „09.05.2017 19:00:00“.