提问人:Ranjit Meher 提问时间:5/29/2023 更新时间:6/6/2023 访问量:223
结尾 0 从 Java11 中 ZonedDateTime 对象的毫秒部分被截断
Ending 0's are getting truncated from millisecond part of ZonedDateTime object in Java11
问:
我正在将我的 Spring Boot 应用程序升级到 Spring Boot 2.7.8 和 Java 11。升级后,我得到了 ZonedDateTime 对象的不同 rest 响应。
我的请求包含“2023-06-23T18:13:06。630元Z[UTC]“,并且我在响应中返回与 Map 键相同的请求对象。但作为回应,从毫秒部分开始结束 0 被修剪“2023-06-23T18:13:06。63Z[UTC]”。
Request:
{
"dateList": [
"2023-06-23T18:13:06.630Z[UTC]"
]
}
Response:
{
"dateList": {
"2023-06-23T18:13:06.63Z[UTC]": "2023-06-23T11:13:06.630-07:00"
}
}
之前有人遇到过这个问题吗?
此问题的任何解决方案,由于我用作 ZonedDateTime 的 Map 键,因此我需要保持一致。
答:
1赞
Soheil Babadi
5/29/2023
#1
这是 Jackson 的一个已知问题,会影响对象的序列化。ZonedDateTime
此问题是由于 Jackson 默认使用 Java 的内置 DateTimeFormatter 来序列化和反序列化日期和时间,因此此格式不会以毫秒为单位保留尾随零。
若要解决此问题,可以将 Jackson 配置为使用自定义日期/时间格式,该格式以毫秒为单位保留尾随零
我尝试了这个,并通过为杰克逊创建一个自定义配置:
@Configuration
public class JacksonConfig {
@Value("${spring.jackson.date-format}")
private String dateFormat;
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
return builder -> {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
builder.simpleDateFormat(dateFormat).serializers(new ZonedDateTimeSerializer(formatter));
builder.deserializers(new ZonedDateTimeDeserializer(formatter));
};
}
public static class ZonedDateTimeSerializer extends StdSerializer<ZonedDateTime> {
private final DateTimeFormatter formatter;
public ZonedDateTimeSerializer(DateTimeFormatter formatter) {
super(ZonedDateTime.class);
this.formatter = formatter;
}
@Override
public void serialize(ZonedDateTime value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeString(formatter.format(value));
}
}
public static class ZonedDateTimeDeserializer extends StdDeserializer<ZonedDateTime> {
private final DateTimeFormatter formatter;
public ZonedDateTimeDeserializer(DateTimeFormatter formatter) {
super(ZonedDateTime.class);
this.formatter = formatter;
}
@Override
public ZonedDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String value = p.getValueAsString();
return ZonedDateTime.parse(value, formatter);
}
}
}
P.S :此外,您还可以使用此格式化程序来格式化您的 ZonedDateTime 对象,然后再将它们添加到地图中:
ZonedDateTime zdt = ZonedDateTime.parse("2023-06-23T18:13:06.630Z[UTC]");
String formatted = zdt.format(formatter);
Map<String, String> response = new HashMap<>();
response.put(formatted, zdt.toString());
评论
1赞
Ranjit Meher
5/29/2023
感谢您@Soheil的回答,但这无济于事。我尝试了这个解决方案,仍然遇到同样的问题。
0赞
Ranjit Meher
5/29/2023
当 Jackson 序列化其余 API 响应时,我遇到了这个问题,在序列化尾随 0 之前,一旦从毫秒序列化 0 就会被截断。
0赞
Ranjit Meher
6/6/2023
您能建议您使用了哪个${spring.jackson.date-format}吗?
0赞
Soheil Babadi
6/6/2023
@RanjitMeher 我在答案中添加了 P.S
0赞
Ranjit Meher
6/6/2023
我无法更改 MAP 键数据类型,因为它在其他应用程序中具有依赖关系。直到我的休息控制器返回 Response<T> 线点 MAP 具有预期值。一旦它到达 Spring 库,它的序列化值就会发生变化。
评论