英文:
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.630Z[UTC]",而我在响应中将相同的请求对象作为Map键返回。但在响应中,毫秒部分的末尾0被截掉了,变成了"2023-06-23T18:13:06.63Z[UTC]"。
请求:
{
"dateList": [
"2023-06-23T18:13:06.630Z[UTC]"
]
}
响应:
{
"dateList": {
"2023-06-23T18:13:06.63Z[UTC]": "2023-06-23T11:13:06.630-07:00"
}
}
有人之前遇到过这个问题吗?
对于这个问题有任何解决方案吗?由于我正在将其用作ZonedDateTime的Map键,所以需要保持一致性。
英文:
I am upgrading my spring boot application to spring boot 2.7.8 and Java 11. I getting different rest response of ZonedDateTime object after upgrade.
My request contain "2023-06-23T18:13:06.630Z[UTC]", and I am returning same request object as a Map key in response. But in response ending 0's from millisecond part getting trimmed "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"
}
}
Did someone faced earlier this issue?
Any solution to this issue, As I am using as Map key of ZonedDateTime, I need to keep it consistent.
答案1
得分: 1
这是一个已知的与Jackson相关的问题,影响了ZonedDateTime
对象的序列化。
这个问题是由于Jackson默认使用Java内置的DateTimeFormatter来序列化和反序列化日期和时间,因此这种格式不会保留毫秒部分的尾随零。
要解决这个问题,你可以配置Jackson使用自定义的日期/时间格式,以保留毫秒部分的尾随零。
我尝试过通过创建一个自定义的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);
}
}
}
另外,你也可以使用这个格式化器在将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());
英文:
This is a known issue with Jackson that affects the serialization of ZonedDateTime
objects.
This issue is caused by the fact that Jackson by default uses Java's built-in DateTimeFormatter to serialize and deserialize dates and times, so this format does not preserve trailing zeros in milliseconds.
To fix this issue, you can configure Jackson to use a custom date/time format that preserves trailing zeros in milliseconds
I tried this and by creating a custome config for 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 :Also you can use this formatter to format your ZonedDateTime objects before adding them to the map:
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());
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论