Spring boot + Jackson - 始终将日期转换为 UTC

Posted

技术标签:

【中文标题】Spring boot + Jackson - 始终将日期转换为 UTC【英文标题】:Spring boot + Jackson - Always convert dates to UTC 【发布时间】:2018-02-24 18:09:12 【问题描述】:

我将日期保存在我的数据库中没有时间戳,所以我想标准化 Spring Boot Rest 控制器接收日期的方式,以便可以在世界任何地方部署服务(AWS EC2 等)。

我尝试设置以下属性,但没有帮助:

spring.jackson.time-zone=UTC

还有一个属性,一直是true,所以我没有设置,就是:

spring.jackson.deserialization.adjust-dates-to-context-time-zone=true

我正在部署到 2 个单独的 Ubuntu 容器,一个位于 UTC 时区,另一个位于我当前的时区 America/Sao_Paulo,即 (GMT -3)。

示例负载:

"date":"2017-09-15T18:58:00.000Z"

当服务部署在圣保罗时,它会收到:

2017-09-15 18:58:00.000000

哪个正确

当服务部署在 UTC 上时,它会收到:

2017-09-15 15:58:00.000000

这是不正确

我在 Java 中使用LocalDateTime 存储日期信息。

示例模型:

import java.time.LocalDateTime;

class Model 
    private LocalDateTime date;

    public LocalDateTime getDate() 
        return date;
    

    public void setDate(LocalDateTime date) 
        this.date = date;
    

示例资源:

@RestController
class Resource 
    @RequestMapping(consumes = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<?> add(@RequestBody Model model) 
        System.out.println(model.getDate());
        // persistence ommited
        return ResponseEntity.created(URI.create("")).build();
    

我无法更改所有生产机器的时区,我必须使用 Jackson 和 Java 解决这个问题(如果可能)。

另一个限制:不能注释我的模型类来做到这一点。

我的pom.xml(相关部分)

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.3.RELEASE</version>
</parent>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.8.5</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
    <version>2.8.5</version>
</dependency>

【问题讨论】:

【参考方案1】:

我在生产环境中也遇到过类似的问题。 我已经在我的 Application.java (具有 main 方法的类)中使用此方法解决了它:

@PostConstruct
void started() 
    TimeZone.setDefault(TimeZone.getTimeZone("Etc/UTC"));

希望对你有帮助。

【讨论】:

我试过了,但问题仍然存在。我的服务器之间有 3 小时的差异(这是 UTC 与我的时区的差异)。 通过这个技巧,您可以强制转换每个接收到的 UTC 日期,以便接收到的日期可以存储在您的数据库中。在我的系统中,我没有使用 LocalDateTime,但我使用的是 Date 和 java.sql.Timestamp。 您的答案确实有效,问题是我的数据库配置。谢谢。 此解决方案更改了整个 JVM 的 TimeZone。这意味着它会影响服务器上运行的其他应用程序,这并不理想:( Java 8 LocalDateTime 不考虑时区,任何杰克逊设置都将被忽略。而是使用 ZondedDateTime,适用于 Hibernate 5+

以上是关于Spring boot + Jackson - 始终将日期转换为 UTC的主要内容,如果未能解决你的问题,请参考以下文章

Jackson 在我的 Spring Boot 应用程序中忽略了 spring.jackson.properties

如何在 Spring Boot 1.4 中自定义 Jackson

Spring Boot没有使用Jackson Kotlin插件

Spring Boot 未使用 Jackson Kotlin 插件

spring-boot用jackson改变json响应结构

Spring boot + Jackson + LocalDateTime:日期解析不正确