I have a problem with Jackson in SpringBoot. My controller returns dates in format yyyy-MM-dd'T'HH:mm:ss'Z', but I need yyyy-MM-dd'T'HH:mm:ss.SSS'Z' (for mwl-calendar in angular which uses date-fns library).
Controller:
@GetMapping(value = "/slots", produces = MediaType.APPLICATION_JSON_VALUE)
public Set<SlotResponse> timeSlots() {
return slotService.getSlots();
}
SlotResponse:
@Data
public class SlotResponse {
private Instant start;
private Instant end;
}
Additional dependency:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
I tried:
@JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") annotationspring.jackson.date-format=yyyyMMddTHH:mm:ss.SSSZ configuration@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
return mapper;
}
SerializationFeature.WRITE_DATES_WITH_ZONE_ID and SerializationFeature.WRITE_DATES_WITH_CONTEXT_TIME_ZONEBut all of this didn't take effect. Everytime I see this result:
[{"start":"2023-05-11T16:00:00Z","end":"2023-05-11T17:00:00Z"}]
I use Java 17, SpringBoot 2.7.0, Jackson 2.13.3
What is wrong?
You can create custom json serializer for Instant type:
public static class InstantSerializer extends StdSerializer<Instant> {
public InstantSerializer() {
super(Instant.class);
}
@Override
public void serialize(
@Nullable final Instant value,
@NonNull final JsonGenerator jsonGenerator,
@NonNull final SerializerProvider serializerProvider
) throws IOException {
if (value != null) {
final DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
.withZone(ZoneId.systemDefault());
final String text = formatter.format(value);
jsonGenerator.writeString(text);
}
}
}
Then use it on the field that you want to follow the format:
@Data
public class SlotResponse {
@JsonSerialize(using = InstantSerializer.class) // Add this
private Instant start;
@JsonSerialize(using = InstantSerializer.class) // Add this
private Instant end;
}
In case you want to make this apply for your whole system, you can add the serializer to jackson:
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
...
final SimpleModule module = new SimpleModule();
module.addSerializer(new InstantSerializer());
mapper.registerModule(module);
...
return mapper;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With