2

I have a Spring Boot application (2.4.1), where an OffsetDateTime field is returned as float value from RestController. Example:

"created_at": 1616080724.531610100

I tried all the suggested solutions in this thread. None of them worked for me.

I also tried to add a very simple end-point that only returns OffsetDateTime:

@GetMapping("/test")
public OffsetDateTime test() {
    return OffsetDateTime.now();
}

The result is the same, it's returned as float value.

Then I tried the same end-point in a minimal Spring Boot project and it's returned in ISO format as expected:

"2021-03-18T15:39:14.5295632+01:00"

This all points to some transitive dependency messing up with the default Jackson serializers used by Sprint Boot. But mvn dependency:tree doesn't give me any suspicious dependencies (e.g. no gson marshaller dependency).

I also tried enabling TRACE logging, and I can see that the object written in HttpEntityMethodProcessor has the correctly formatted created_at time:

TRACE org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor - Writing [class MyObject {
....
createdAt: 2021-03-18T16:37:34.113316500+01:00
...

But it still ends up as float on the client side (testing on browser and with Postman). What could be the problem here?

Egemen
  • 2,178
  • 5
  • 22
  • 32

2 Answers2

5

After some debugging in Jackson classes, I found out that InstantSerializerBase#serialize method was being called with the default SerializerProvider (DefaultSerializerProviderImpl), which had the SerializationFeature.WRITE_DATES_AS_TIMESTAMPS feature enabled. That resulted in serializing OffsetDateTime values as epoch seconds + nanos.

I was able to fix the problem by adapting our WebMvcConfigurer implementation as follows:

@Configuration
@EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer {

    // Some other configuration

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new MappingJackson2HttpMessageConverter(objectMapper()));
    }

    private ObjectMapper objectMapper() {
        return new ObjectMapper()
            .disable(WRITE_DATES_AS_TIMESTAMPS)
            .registerModule(new JavaTimeModule());
    }
}

After this change, OffsetDateTime fields are finally serialized in ISO format; e.g.

"created_at": "2021-03-19T17:05:27.785646+01:00"
Egemen
  • 2,178
  • 5
  • 22
  • 32
0

Soution with configureMessageConverters is exacty what I needed. I have the same problem and you really helped me. Thanks!

Maybe you should report the solution to Spring

O.Voronin
  • 3
  • 1
  • 3