SpringBoot中 Jackson 日期的时区和日期格式问题解决

目录
  • 1、使用场景
    • 1.1、数据库MySQL也是有时区的概念的。
    • 1.2、系统时区意味着与计算机的操作系统时区相同。
    • 1.2、SpringBoot默认的Json视图转换框架Jackson也有时区概念
  • 2、代码实现
    • 2.1、解决方案一下在每个带有日期地方加上注解
    • 2.2、只需要配置一个bean实现整体修改
    • 2.3、使用SpringBoot的配置方式
  • 3、成果展现
  • 4、总结

1、使用场景

因为最近项目需要国际化,需要能够支持多种国际化语言,目前需要支持三种(法语、英语、简体中文)。我们的项目部署环境为使用阿里云(德国)节点。以前我们项目主要用户在中国国内。一部署到德国服务器节点就出现一个问题了。数据返回的时间不对,存储的时间也有时差了。此文章仅仅与UTC标准时间与北京时间(东八区时间)作为实际例子。最后跟踪发现,如下几点原因:

1.1、数据库MySQL也是有时区的概念的。

通过如下命令可以查询MySQL的时区

 show variables like "%time_zone%";

如果未做任何修改会显示如下:

+------------------+--------+
| Variable_name  | Value |
+------------------+--------+
| system_time_zone | CST  |
| time_zone    | SYSTEM |
+------------------+--------+
2 rows in set (0.00 sec)
#time_zone说明mysql使用system的时区,system_time_zone说明system使用CST时区

1.2、系统时区意味着与计算机的操作系统时区相同。

以下是我们北京时间使用MySQL时区

 set global time_zone = '+8:00'; ##修改mysql全局时区为北京时间,即我们所在的东8区
> set time_zone = '+8:00'; ##修改当前会话时区
> flush privileges; #立即生效

或者通过修改MySQL的 my.cnf配置文件来修改时区
# vim /etc/my.cnf ##在[mysqld]区域中加上
default-time_zone = '+8:00'
# /etc/init.d/mysqld restart ##重启mysql使新时区生效

1.2、SpringBoot默认的Json视图转换框架Jackson也有时区概念

Jackson日期反序列化时区问题,Jackson里 JsonFormat的源码

/**
 * Value that indicates that default {@link java.util.TimeZone}
 * (from deserialization or serialization context) should be used:
 * annotation does not define value to use.
 *<p>
 * NOTE: default here does NOT mean JVM defaults but Jackson databindings
 * default, usually UTC, but may be changed on <code>ObjectMapper</code>.
 */
public final static String DEFAULT_TIMEZONE = "##default";

值,该值指示默认{@链接java.util.TimeZone}

(来自反序列化或序列化上下文)应使用:

注释未定义要使用的值。

注意:这里的默认值并不意味着JVM默认值,而是Jackson数据绑定。

默认值,通常为UTC,但可以在<code>objectmapper<code>上更改。

那个注释已经说明默认情况下会将 时区设置为UTC ,Jackson反序列化时间类型的底层实际上调用的是Java的 SimpleDateFormat#parse() 方法,而JVM中的时区则会根据你的操作系统来获取,所以JVM认为你的时区应该是 GMT+8 时区,
而要将 UTC 时区的时间转成 GMT+8 时区的时间,就会将你传进来的时间+8个小时。

2、代码实现

2.1、解决方案一下在每个带有日期地方加上注解

日期类型的字段上的 @JsonFormat 加上属性 timezone="GMT+8"

@NotNull
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
@JsonProperty("start_time")
private Date startTime;

此类方法需要在包含日期地方都加上注解属性,比较繁琐。

2.2、只需要配置一个bean实现整体修改

@Bean
    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
        return jacksonObjectMapperBuilder ->
                jacksonObjectMapperBuilder.timeZone(TimeZone.getTimeZone("GMT+8"));
    }

参考文章:Jackson日期反序列化时区问题

2.3、使用SpringBoot的配置方式

spring.jackson.default-property-inclusion=NON_NULL
spring.jackson.time-zone=GMT+8
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss

第一个设置就是使用24小时的时间格式;第二个设置就是设置时区为东八区。

但是配置时候需要注意

Finally, if you opt out of the Spring Boot default MVC configuration by providing your own @EnableWebMvc configuration, you can take control completely and do everything manually by using getMessageConverters from WebMvcConfigurationSupport.

《Spring Boot Reference Guide》

需要去掉

@EnableWebMvc

参考文章:

SpringBoot升级指定jackson版本的问题

SpringBoot利用jackson格式化时间的三种方法

java如何利用FastJSON、Gson、Jackson三种Json格式工具自定义时间序列化

3、成果展现

经过转换配置转换之后;能够正确的获得和存取对应的时间,建议使用

        2.2、只需要配置一个bean实现整体修改 或者使用 2.3、使用SpringBoot的配置方式 方式比较通用性。

其中如果使用FastJson转换也可能遇见同样的问题,可以参考文章

springmvc fastjson 反序列化时间格式化方法(推荐)

4、总结

在SpringBoot开发应用之中设计日期转换需要特别注意,能够主要目标能够是的存储和返回的日期能够对应上自己的本地时区。同时能够使用较为通用的转换方式解决相关问题。

(0)

相关推荐

  • SpringBoot2.0整合jackson配置日期格式化和反序列化的实现

    网上杂七杂八的说法不一,大多数都是抄来抄去,没有实践,近期在项目频繁遇到boot+jackson处理日期的问题,故开此贴. 首先是POM <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance

  • SpringBoot中Jackson日期格式化技巧分享

    目录 Jackson 日期格式化技巧 后续问题 补充:Jackson 统一配置 日期转换格式 参考资料 Jackson 日期格式化技巧 使用 Spring Boot 时,需要使用 Jackson 处理一些 Java Time API 类型的 JSON 序列化问题,在处理一些类的字段时,可以通过直接在属性上加注解的方式来指定其格式化样式.但是,昨天同事遇到一个格式化 Map 数据的问题,这样就不能通过加注解来解决格式化样式的问题了. 在网上各种搜索,各种尝试后,终于解决了这个问题,记录一下,以备不

  • SpringBoot中时间类型 序列化、反序列化、格式处理示例代码

    [SpringBoot] 中时间类型 序列化.反序列化.格式处理 Date yml全局配置 spring: jackson: time-zone: GMT+8 date-format: yyyy-MM-dd HH:mm:ss #配置POST请求Body中Date时间类型序列化格式处理,并返回 请求参数类型转换 /** * 时间Date转换 * 配置GET请求,Query查询Date时间类型参数转换 */ @Component public class DateConverter implemen

  • SpringBoot中 Jackson 日期的时区和日期格式问题解决

    目录 1.使用场景 1.1.数据库MySQL也是有时区的概念的. 1.2.系统时区意味着与计算机的操作系统时区相同. 1.2.SpringBoot默认的Json视图转换框架Jackson也有时区概念 2.代码实现 2.1.解决方案一下在每个带有日期地方加上注解 2.2.只需要配置一个bean实现整体修改 2.3.使用SpringBoot的配置方式 3.成果展现 4.总结 1.使用场景 因为最近项目需要国际化,需要能够支持多种国际化语言,目前需要支持三种(法语.英语.简体中文).我们的项目部署环境

  • SpringBoot整合Jackson超详细用法(附Jackson工具类)

    目录 一.Jackson简介 二.Json简介 三.springboot整合Jackson 1.创建项目 2.导入坐标 3.配置文件 4.实体类 5.测试类 一.Jackson简介 说明:本篇讲的是Jackson的详细用法,Jackson工具类在文章最后,直接复制粘贴即可使用. Jackson是公司中必用的组件之一,常用的还用阿里的Fastjson,但是由于一些原因bug与漏洞是在是太多,在注重安全的公司直接被pass,还有就是谷歌的Gson(这个没用过不太了解). Spring MVC 的默认

  • Springboot中如何使用Jackson

    1.SpringMVC中默认集成 SpringMVC已经默认集成了JackSon,如下所示: @RequestMapping("/addUserInfo") public UserInfo addUserInfo(@RequestBody UserInfo userInfo){ } 可以用UserInfo对象来接前台传过来的json,SpringMVC已经帮我们自动反序列化. 可以看到,在SpringBoot中,只需要导入web starter,不需要添加其他的依赖,就可以使用Jack

  • jackson在springboot中的使用方式-自定义参数转换器

    目录 springboot jackson使用-自定义参数转换器 要实现的功能 思路 关键代码 Jackson自定义转换器 @JsonDeserialize注解源码 以日期类型为例 自定义转换方法 springboot jackson使用-自定义参数转换器 springboot中默认使用jackson,且实现了很多参数转换器,其中就有EnumToStringConverter和StringToEnumConverterFactory,用于字符串和枚举的互转.但是是根据枚举名称互转. 要实现的功能

  • 详解 Java中日期数据类型的处理之格式转换的实例

    详解 Java中日期数据类型的处理之格式转换的实例 概要: 日期以及时间格式处理,在Java中时间格式一般会涉及到的数据类型包括Calendar类和Date类. Date类: 1.Date类型转String类型(以时间格式1970-01-01 01:01:01为例) //yyyy-MM-dd HH:mm:ss表示24时间进制 SimpleDateFormat sDateFormat=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String

  • 在Linux系统中如何使用ls命令按日期对文件进行排序

    ls命令用于列出目录内容,结果可以按几个条件排序,例如按日期,按字母顺序排列的文件名,修改时间,访问时间,版本和文件大小. 在本文中,我将向您展示如何使用Linux中的ls命令按日期对文件进行排序. 1)列出具有上次修改日期/时间的文件目录 要列出文件并在顶部显示最后修改的文件,我们将使用-lt选项和ls命令. [linuxidc@localhost www.linuxidc.com]$ ls -lt /run 输出如下: 总用量 60 -rw-rw-r--. 1 root utmp 1536

  • python 带时区的日期格式化操作

    如下所示: Wed, 23 Oct 2019 21:12:01 +0800 Wed, 23 Oct 2019 06:08:37 +0000 (GMT) Fri, 11 Oct 2019 12:42:07 +0800 (CST) Wed, 23 Oct 2019 06:08:37 +0000 (UTC) 几种不同的日期格式化方式,不同的时区时间转换成北京时间,也就是东八区的时间,注意的是后面的时区表示方式, def getTimeStamp(self, date): result = re.sea

  • Spring boot中Jackson的操作指南

    前言 有一段时间没写博客了,虽然是菜鸟一枚但毕竟总要有东西记录学习的,我相信有志者事竟成.今天在工作中使用Jackson转换了一个javabean,传到测试服上之后发现日期少了一天,使用的是@JsonFormat注解. Spring-Boot是基于Spring框架的,它并不是对Spring框架的功能增强,而是对Spring的一种快速构建的方式. 好了,下面话不多说了,来一起看看详细的介绍吧 这里写了一个简单的小demo记录一下: 表数据: 实体类属性: controller层就省略掉了,就是调用

随机推荐