Jackson日期反序列化时区问题

今天遇到了一个坑爹的问题,当用Jackson对Json中的日期类型进行反序列化时,出现了日期错误的问题,当时写法是这样的:

@Data
@NoArgsConstructor
public class TotalByAccessIdRest {

    @NotNull
    @JsonProperty("access_id")
    private String accessId;

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

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonProperty("end_time")
    private Date endTime = new Date();
}

按平时来看,好像根本没有什么问题。但当你发送请求,比如你发送startTime或者endTime参数值为2018-04-13 00:00:00时间时,在Controller端实际你收到后的值就变成了2018-04-13 08:00:00,为什么会这样子呢?

让我们进入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";

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

解决方案:

  1. 在你每个日期类型的字段上的 @JsonFormat 加上属性 timezone="GMT+8"
    @NotNull
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    @JsonProperty("start_time")
    private Date startTime;

这种解决方法会让你在每个日期类型上都加上这么一个属性,比较繁琐。

  1. 还有一种操作,只需要配置一个bean就行,代码如下:
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
        return jacksonObjectMapperBuilder ->
                jacksonObjectMapperBuilder.timeZone(TimeZone.getTimeZone("GMT+8"));
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 概念解释 时区(Timezone) 为什么会将地球分为不同时区呢?因为地球总是自西向东自转,东边总比西边先看到太阳...
    黑炭妈阅读 6,901评论 0 5
  • 时间(date time)应该是一个精确的点,以便能够进行比较。但是如何能让他成为一个精确的点呢?一般的,如果需要...
    远程板砖阅读 1,877评论 1 8
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,270评论 0 4
  • 伴随lambda表达式、streams以及一系列小优化,Java 8 推出了全新的日期时间API。Java处理日期...
    zheting阅读 1,536评论 0 2
  • 因为工作原因,今天比往常早起了一些,虽然入秋有点凉,可是依然挡不住早起的幸福感。 坐在公交车上,打开音乐播放器,戴...
    男是小男的男阅读 168评论 0 0