Can't serialize java.time.LocalDate as a String with Jackson
Asked Answered
S

4

10

I am using spring-boot 1.2.1.RELEASE with jackson 2.6.2 including the jsr310 datatype. I am using the annotation @SpringBootApplication to kick off my Spring app. I have

spring.jackson.serialization.write_dates_as_timestamps = false

set in my application.properties (which I know is being read because I tested with banner = false).

And yet java.time.LocalDate is still being serialized as an array of integers. I am not using @EnableWebMvc.

It looks like if I add the tag

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")

to my LocalDate variable then it works. But I thought it was automatic with the above property set. Plus, if I remember right (I've since just decided to work with the integer array), that only worked with serialization and not deserialization (but I can't honestly quite remember if that last part is true).

Squab answered 5/10, 2015 at 15:27 Comment(4)
Have you registered Jackson module for JSR310? objectMapper.registerModule(new JavaTimeModule());Madigan
That is automatically done by spring-boot and I know that it is because without the jackson-datatype-jsr310 addition to my pom.xml I get the default complex serialization for LocalDate. When I add in the datatype, I get the integer array serialization.Squab
Wrt deserialization: both forms should be acceptable, regardless of serialization settings. But if you use custom textual format, that is needed for deserialization as well.Malinin
A few years ago I updated to spring boot 2.X (currently on 2.1.9.RELEASE) and all of this was unnecessary. Out of the box, it converts to a string, no configuration necessary.Squab
I
10

This is know issue in Spring Boot. You need to do it manually.

objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

or update to 1.2.2.

UPDATE: Also there is a way to configure ObjectMapper used by spring from your container.

Impalpable answered 6/10, 2015 at 3:58 Comment(3)
I am on 1.2.6 now and it still ignores that property. Also, how do you get to the objectMapper without using WebMvc? All the incidents on the web I find involve using WebMvc which I am not using.Squab
Added a link to the answerImpalpable
Looks like according to that answer the property configuration will not be available till 1.3 is released. Thanks for the link to that.Squab
H
3

I had the same problem of LocalDateTime being serialized as an array of integers like [2019,10,14,15,7,6,31000000]. The spring boot version I had was 1.5.13.RELEASE. I had to register the JavaTimeModule on the ObjectMapper being used to solve this. Below is my ObjectMapper config that worked for me:

@Bean
  public ObjectMapper getObjectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    mapper.registerModule(new JavaTimeModule());
    return mapper;
  }
Harmonious answered 15/10, 2019 at 5:40 Comment(0)
U
0

This problem happened to me in a weird way... using different spring profiles, one of them returned an array of integers and the another returned the expected result (year-month-day).

After review my configuration, the problem was the lack of @Configuration and (maybe) the @Primary in my class... This is not explain why could be work in different profiles, but this follow setting resolved my problem:

@Configuration
public class WebConfigurer {

    @Bean
    @Primary
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.build();
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        return objectMapper;
    }

}

And, of course, you still need the dependency for JSR 310 in the pom.xml.

Unhouse answered 22/12, 2017 at 15:36 Comment(0)
P
0

Here is what I did in my WebConfig.java:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

  // other configs

  @Override
  public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    WebMvcConfigurer.super.extendMessageConverters(converters);
    converters.add(new MappingJackson2HttpMessageConverter(
        new Jackson2ObjectMapperBuilder()
            .dateFormat(new StdDateFormat())
            .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .build()));
  }

}
Pincus answered 15/2, 2023 at 16:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.