LocalDateTime is representing in array format
Asked Answered
P

3

8

I am using spring boot 2.2.6 and Jackson 2.10.3 with Java 8. I am using localdatetime objects through out my project. Jackson is not able to parse LocalDateTime properly (or may be it's default format) and sending date in json response as in array format like below

        "createdDate": [
            2020,
            8,
            31,
            0,
            0,
            0,
            80000000
        ]

As described in JSON Java 8 LocalDateTime format in Spring Boot , Spring boot 2 has already default jackson-datatype-jsr310:2.10.3 on classpath. I want dates to represent in json as 2020-03-31:00 in whole project. First solution doesn't work in the above link. After that i have tried @JsonSerialize annotation and it works but i don't want to apply on each and every class. So also tried to override object mapper but it didn't work

@Primary
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
        SimpleModule module = new SimpleModule("my custom date serializer");
        module.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer());
        mapper.registerModule(module);
        return mapper;
    }

Also tried to customize Jackson2ObjectMapperBuilder, but still have date in array format

@Bean
    public Jackson2ObjectMapperBuilder objectMapperBuilder() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.serializationInclusion(JsonInclude.Include.NON_NULL);
        builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        SimpleModule module = new SimpleModule("my custom date serializer");
        module.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer());
        builder.modulesToInstall(modules)
        return builder;
    }

Tried with also Jackson2ObjectMapperBuilderCustomizer

@Configuration
public class JacksonConfiguration {

    @Primary
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
        return builder -> {
            builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
            builder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        };
    }
}

Contoller

@RestConroller
@RequestMapping("/user")
UserController {

    User getUser(){
        User user = new User()
        user.createdDate = LocalDateTime.now();
        return user;
    }

}

is there anything i can do at global level, so every date in the project will be serialized as in string format like 2020-09-01 ?

Any suggestion will be helpful.

Parfleche answered 1/9, 2020 at 6:41 Comment(0)
P
24

The culprit was @EnableWebMVC. One of my cors class was having @EnableWebMVC annotation. This was disabling the spring boot auto configuration and also overriding the mapper confiiguration. This won't let you to override the configuration of object mapper. By removing @EnableMVC annotation, this is working fine now. In SpringBoot2, we don't need to do any configuration explicitly related to date serialization, it will automatically parse the java 8 dates in "yyyy-mm-dd" format.

Parfleche answered 2/9, 2020 at 4:9 Comment(3)
After getting lost looking for answers, thank you for sharing this. Worked like a charm!Egor
So if I remove @EnableWebMVC does this effect cors configuration?Flam
No .. I don't think so.Parfleche
U
4

use below Jackson annotation on date fields of User model :

@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
Unfreeze answered 19/8, 2022 at 10:48 Comment(1)
This approach fixed my issue. I was using annotation based property configuration ``` java @JsonProperty @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") @JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonSerialize(using = LocalDateTimeSerializer.class) private LocalDateTime operationStart; ```Shine
C
1

Create a Jackson2ObjectMapperBuilderCustomizer bean:

@Bean
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
    return builder -> {
        builder.simpleDateFormat(dateTimeFormat);
        builder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern(dateFormat)));
        builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(dateTimeFormat)));
    };
}

Add property spring.jackson.serialization.write_dates_as_timestamps=false to application.properties or you can also do it programmatically in the Jackson2ObjectMapperBuilderCustomizer.

Calmas answered 1/9, 2020 at 6:50 Comment(5)
@PrabjotSingh It sounds like you're serializing from a place out of Spring's control. Post your serialization code.Calmas
I have edited the question. Added Jackson2ObjectMapperBuilderCustomizer code and controller code.Parfleche
Still having the same issue, tried using prop files and using java config too.Parfleche
@PrabjotSingh Sorry, I don't know how else to help you. Debug your code yourself.Calmas
Thanks sir for you help, I got the answer. I posted it.Parfleche

© 2022 - 2024 — McMap. All rights reserved.