dre*_*nda 1 java rest spring spring-mvc spring-data-rest
我正在使用 Spring Boot 1.5.4、Hibernate 5.2.10、Spring Data REST、HATEOAS、带有 LocalDate 和 LocalDateTime 的 JDK8。我的电脑在 CEST 时区,但我希望应用程序在 UTC 中工作,所以我在 application.properties 中设置:
spring.datasource.url=jdbc:mysql://localhost:3306/database?useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=true
spring.jpa.hibernate.jdbc.time_zone = UTC
Run Code Online (Sandbox Code Playgroud)
根据这篇文章,我不想更改 JVM 的时区,因为这似乎不是最佳实践。
Spring Data REST 公开了我的存储库,我使用 Swagger2 有一个很好的界面来使用 API。当我尝试一个端点时,我看到如下内容:
{
"_embedded": {
"dailyCodes": [
{
"sid": "d495cdaa-14f2-44cb-a98f-8aa6ddd43d91",
"createdDate": "2017-06-28T16:20:01",
"lastModifiedDate": "2017-06-28T16:20:01",
"lastModifiedBy": "admin",
"date": "2017-06-28",
"code": "js",
"new": false,
"_links": {
"self": {
"href": "http://localhost:8080/api/v1/dailyCodes/1"
},
"dailyCode": {
"href": "http://localhost:8080/api/v1/dailyCodes/1"
}
}
}
Run Code Online (Sandbox Code Playgroud)
Like you can see the datetime format is fine and also it display the CEST time even if in the db the real time is 14:20:01. I guess this is wrong because my REST API should work in UTC.
How could I achieve this result?
Always on the same topic, I've a REST endpoint (exposed by Spring Data REST) to search using LocalDate params; I'm using
@Transactional
@PreAuthorize("isAuthenticated()")
public interface DailyCodeRepository extends PagingAndSortingRepository<DailyCode, Long> {
@Query("SELECT d FROM DailyCode d WHERE (:code IS NULL or code=:code) AND (:from IS NULL OR date>=:from) AND (:to IS NULL OR date<=:to)")
public Page<DailyCode> findAllWithParameter(@Param("code") @RequestParam(value = "code", required = false) String code,
@Param("from") @RequestParam(value = "from", required = false) LocalDate from,
@Param("to") @RequestParam(value = "to", required = false) LocalDate to, Pageable pageable);
}
Run Code Online (Sandbox Code Playgroud)
Also in this case I've a strange thing: if I call the endpoint passing parameters, in the server they arrive with 1 day less. Furthemore the date pattern accepted seems to be the JDK default of my locale (Italian) but I guess it's not a best practice.
Is there a best practice to follow to avoid any problems with date/time arguments in both direction?
我同意这篇文章的作者我们必须在 UTC 中存储和返回时间的 API 日期和时间的 5 条法则。并且“前端”必须自己决定如何根据客户端时区转换时间值。
为了实现这一点(以 UTC 存储和返回时间),我们设置 JVM 参数-Duser.timezone=UTC
或添加spring.jpa.properties.hibernate.jdbc.time_zone=UTC
到application.properties
(从 Hibernate 5.2.3.Final 开始)。然后将我们实体的时间字段从LocalDateTime
(不存储时区信息)更改为ZonedDateTime
type。
之后,时间值将以 UTC 独立于启动应用程序的计算机的本地时区存储,SDR 将以ISO8601格式返回这些值:2017-07-02T11:58:10.089Z
但是如果有必要返回特定时区的时间值,我们必须为我们所有的时间字段设置 @JsonFormat 注释:
@JsonFormat(timezone = "Europe/Rome", pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
private ZonedDateTime createdDate;
Run Code Online (Sandbox Code Playgroud)
我们可以定义常量TIME_ZONE
在我们的应用程序,并将其设置在@JsonFormat注释:@JsonFormat(timezone = Application.TIME_ZONE, ...)
。
然后我们得到这个输出:
{
//...
"createdDate": "2017-07-02T14:11:45.964+0200",
//...
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,参数spring.jackson.time-zone
(基于我的简短调查)仅影响应用程序中的服务消息,例如:
{
"timestamp": "2017-07-02T14:14:09.486+0200",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/users"
}
Run Code Online (Sandbox Code Playgroud)
要以“分区”形式在此处获取时间,我们必须在以下位置正确设置spring.jackson.date-format
参数application.properties
:
spring.jackson.date-format=com.fasterxml.jackson.databind.util.StdDateFormat
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9276 次 |
最近记录: |