Spring Boot v4 includes an upgrade from Jackson v2 to v3, which includes many breaking changes. One of these change is the removal of ObjectMapper.registerModules
. In v3 this could be used to register a Jackson module like so
@Configuration
public class JacksonConfiguration {
public JacksonConfiguration(ObjectMapper objectMapper) {
SimpleModule module = new SimpleModule();
module.addSerializer(LocalDateTime.class, new JsonSerializer<>() {
@Override
public void serialize(LocalDateTime utcDateTime, JsonGenerator jsonGenerator,
SerializerProvider serializers) throws IOException {
String dateTimeWithZone = utcDateTime.atZone(ZoneOffset.UTC).toString();
jsonGenerator.writeString(dateTimeWithZone);
}
});
module.addDeserializer(LocalDateTime.class, new JsonDeserializer<>() {
@Override
public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException {
String dateTimeWithZone = jsonParser.getValueAsString();
return ZonedDateTime.parse(dateTimeWithZone).toLocalDateTime();
}
});
objectMapper.registerModules(module); // removed in Jackson v3
}
}
In Jackson v3 registerModules
has been removed because ObjectMapper is immutable.
Possibly one could replace the last line above with
objectMapper.rebuild().addModule(module)
An example of how to customise the ObjectMapper
in v4 would be very useful, because I suspect this will be a breaking change for many users.
Update
I suspect the following may be a better solution. I've also updated the serializer and deserializer to the new APIs.
@Configuration
public class JacksonConfiguration implements JsonMapperBuilderCustomizer {
@Override
public void customize(JsonMapper.Builder jsonMapperBuilder) {
SimpleModule module = new SimpleModule();
module.addSerializer(LocalDateTime.class, new ValueSerializer<>() {
@Override
public void serialize(LocalDateTime utcDateTime, JsonGenerator jsonGenerator, SerializationContext ctx) {
String dateTimeWithZone = utcDateTime.atZone(ZoneOffset.UTC).toString();
jsonGenerator.writeString(dateTimeWithZone);
}
});
module.addDeserializer(LocalDateTime.class, new ValueDeserializer<>() {
@Override
public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext context) {
String dateTimeWithZone = jsonParser.getValueAsString();
return ZonedDateTime.parse(dateTimeWithZone).toLocalDateTime();
}
});
jsonMapperBuilder.addModule(module);
}
}
Comment From: philwebb
Have you seen https://docs.spring.io/spring-boot/4.0/reference/features/json.html#features.json.jackson.custom-serializers-and-deserializers ?
Comment From: donalmurtagh
@philwebb I hadn't seen that before. It looks like a much simpler way of registering serializers/deserializers. Thanks very much for the link!