1

I'm trying to achieve something absurdly simple, that is set the global time format to all json serialized in the spring boot application... I've tried many suggestions from other questions but it looks like jackson chooses to ignore whatever configuration i set to object mapper, my code is

@Bean
   public ObjectMapper objectMapper() {
      ObjectMapper mapper = new ObjectMapper();
      JavaTimeModule javaTimeModule = new JavaTimeModule();
      javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm")));
      javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm")));
      mapper.registerModule(javaTimeModule);
      mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
      mapper.configure(SerializationFeature.WRITE_DATES_WITH_CONTEXT_TIME_ZONE, false);
      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);


      return mapper;
   }

if I autowire the ObjectMapper and use it manually like System.out.println(objectMapper.writeValueAsString(LocalDateTime.now())); I get the dates in the format I want.

But all my controllers keep generating json in this format 2022-06-30T22:44:11
All my entities and Dtos use LocalDateTime as time object... What am I missing to make it work?
Please dont suggest annotate all my LocalDateTime to set the pattern, I want a configuration that I can set globally

thanks

Rafael Lima
  • 3,079
  • 3
  • 41
  • 105
  • I would guess your `ObjectMapper` bean isn't being used by the Jackson serialization mechanism used by your controllers. The issue might be something like https://stackoverflow.com/questions/45734108 where a different `ObjectMapper` than expected is being used. – M. Justin Sep 13 '22 at 04:09

2 Answers2

0

Try annotating objectMapper configuration with @Primary. Also article bellow suggests some solutions too https://www.baeldung.com/spring-boot-customize-jackson-objectmapper. If @Primary doesn't work, check that out

Roman
  • 181
  • 7
0

In your situation you did everything well except one thing.

You are adding custom serializer/deserializer. But you are creating new instance of ObjectMapper which is already exist by Spring. Spring has default configuration for ObjectMapper and it sets all necessary serializer/deserializers and other configs. ObjectMapper you have created has only your serializer/deserializer. Spring uses others too, but in your instance they don't exist. That's why just use default and configure itself instead of creating new one.

Your code may looks like

@Configuration
public class DataTimeConfiguration {

@Bean
public ObjectMapper objectMapper(ObjectMapper mapper) {
    var module = new JavaTimeModule();
    module.addSerializer(LocalDateTime.class, new            LocalDateTimeSerializer());
    module.addDeserializer(LocalDateTime.class, new    LocalDateTimeDeserializer());
    mapper.registerModule(module);
    return mapper;
}

public static class LocalDateTimeDeserializer extends   JsonDeserializer<LocalDateTime> {
    @Override
    public LocalDateTime deserialize(JsonParser arg0, DeserializationContext arg1) throws IOException {
        return LocalDateTime.parse(arg0.getText());
    }
}

public static class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
    @Override
    public void serialize(LocalDateTime arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
        arg1.writeString(arg0.toString());
    }
}
}