ZonedDateTime 的时区在使用 Spring 启动自动转换 RequestBody 期间更改为 UTC
Timezone of ZonedDateTime changed to UTC during auto conversion of RequestBody with Spring Boot
我正在尝试保留在前端设置的 ZonedDateTime 的 ZoneId,同时执行 POST/PUT 到 Spring 引导控制器。
我要转账的金额是:
2019-05-01T00:00:00+01:00[Europe/Zagreb]
在 POST/PUT 之后,ZoneId 转换为 UTC 并调整小时数。从技术上讲,这个更新后的值代表时间线上的相同点,但原始 ZoneId 丢失了,我想将其存储起来以便稍后能够将其显示给最终用户。
// DTO
public class PriceInfoDTO {
@JsonFormat( pattern = "yyyy-MM-dd'T'HH:mm:ssXXX['['VV']']",
with = JsonFormat.Feature.WRITE_DATES_WITH_ZONE_ID )
@DateTimeFormat( pattern = "yyyy-MM-dd'T'HH:mm:ssXXX['['VV']']", iso = ISO.DATE_TIME )
private ZonedDateTime validFrom;
}
// Controller
@PutMapping(
path = PATH + "/{id}",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE
)
public ResponseEntity<PriceInfo> update(
@PathVariable("id") final Integer id,
@RequestBody final PriceInfoDTO dto
) {
System.out.println(dto);
...
}
查看我浏览器中的网络选项卡,从浏览器到 Spring 控制器的请求具有此值(有效负载):
2019-05-01T00:00:00+01:00[Europe/Zagreb]
与格式模式相同
当我将 DTO 转储到控制台时,我得到了这个结果:
2019-04-30T22:00Z[UTC]
有什么方法可以保留在请求中收到的 ZoneId 吗?我应该编写自己的序列化器和反序列化器来实现这个吗?
谢谢!
将以下行添加到 application.properties
文件:
spring.jackson.deserialization.ADJUST_DATES_TO_CONTEXT_TIME_ZONE = false
参考文献:
- Baeldung:Jackson 日期: Deserialize Joda ZonedDateTime with Time Zone Preserved
- Javadoc: jackson-databind 2.6.0 API: ADJUST_DATES_TO_CONTEXT_TIME_ZONE
- Spring 引导:“操作方法”指南: Customize the Jackson ObjectMapper
也可以通过编程方式设置 ObjectMapper
:
objectMapper.configure(SerializationFeature.WRITE_DATES_WITH_ZONE_ID, true);
objectMapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);
我正在尝试保留在前端设置的 ZonedDateTime 的 ZoneId,同时执行 POST/PUT 到 Spring 引导控制器。
我要转账的金额是:
2019-05-01T00:00:00+01:00[Europe/Zagreb]
在 POST/PUT 之后,ZoneId 转换为 UTC 并调整小时数。从技术上讲,这个更新后的值代表时间线上的相同点,但原始 ZoneId 丢失了,我想将其存储起来以便稍后能够将其显示给最终用户。
// DTO
public class PriceInfoDTO {
@JsonFormat( pattern = "yyyy-MM-dd'T'HH:mm:ssXXX['['VV']']",
with = JsonFormat.Feature.WRITE_DATES_WITH_ZONE_ID )
@DateTimeFormat( pattern = "yyyy-MM-dd'T'HH:mm:ssXXX['['VV']']", iso = ISO.DATE_TIME )
private ZonedDateTime validFrom;
}
// Controller
@PutMapping(
path = PATH + "/{id}",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE
)
public ResponseEntity<PriceInfo> update(
@PathVariable("id") final Integer id,
@RequestBody final PriceInfoDTO dto
) {
System.out.println(dto);
...
}
查看我浏览器中的网络选项卡,从浏览器到 Spring 控制器的请求具有此值(有效负载):
2019-05-01T00:00:00+01:00[Europe/Zagreb]
与格式模式相同
当我将 DTO 转储到控制台时,我得到了这个结果:
2019-04-30T22:00Z[UTC]
有什么方法可以保留在请求中收到的 ZoneId 吗?我应该编写自己的序列化器和反序列化器来实现这个吗?
谢谢!
将以下行添加到 application.properties
文件:
spring.jackson.deserialization.ADJUST_DATES_TO_CONTEXT_TIME_ZONE = false
参考文献:
- Baeldung:Jackson 日期: Deserialize Joda ZonedDateTime with Time Zone Preserved
- Javadoc: jackson-databind 2.6.0 API: ADJUST_DATES_TO_CONTEXT_TIME_ZONE
- Spring 引导:“操作方法”指南: Customize the Jackson ObjectMapper
也可以通过编程方式设置 ObjectMapper
:
objectMapper.configure(SerializationFeature.WRITE_DATES_WITH_ZONE_ID, true);
objectMapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);