我对 SpringBoot 中的 Jackson 有疑问。我的控制器以
yyyy-MM-dd'T'HH:mm:ss'Z'
格式返回日期,但我需要yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
(对于使用date-fns库的angular mwl-calendar)。
控制器:
@GetMapping(value = "/slots", produces = MediaType.APPLICATION_JSON_VALUE)
public Set<SlotResponse> timeSlots() {
return slotService.getSlots();
}
插槽响应:
@Data
public class SlotResponse {
private Instant start;
private Instant end;
}
附加依赖:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
我试过:
@JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
注释spring.jackson.date-format=yyyyMMddTHH:mm:ss.SSSZ
配置@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
和SerializationFeature.WRITE_DATES_WITH_CONTEXT_TIME_ZONE
但这一切都没有生效。每次看到这个结果:
[{"start":"2023-05-11T16:00:00Z","end":"2023-05-11T17:00:00Z"}]
我使用Java 17、SpringBoot 2.7.0、Jackson 2.13.3
怎么了?
您可以为 Instant 类型创建自定义 json 序列化程序:
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);
}
}
}
然后在您要遵循格式的字段上使用它:
@Data
public class SlotResponse {
@JsonSerialize(using = InstantSerializer.class) // Add this
private Instant start;
@JsonSerialize(using = InstantSerializer.class) // Add this
private Instant end;
}
如果你想让它适用于你的整个系统,你可以将序列化程序添加到 jackson:
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
...
final SimpleModule module = new SimpleModule();
module.addSerializer(new InstantSerializer());
mapper.registerModule(module);
...
return mapper;
}