美文网首页
RestTemplate使用jackson序列化的时区问题

RestTemplate使用jackson序列化的时区问题

作者: fantuanjiaozi | 来源:发表于2018-11-06 18:27 被阅读382次

问题描述

Springboot项目A服务使用restTemplate.postForObject()调用B服务的rest接口,返回的对象内有一个date类型字段,发现date类型比实际时间小了8个小时。


jackson.jpeg

定位问题过程

  • 查看B服务的日志信息,实际数据:2018-11-05 10:56:09返回的没有任何问题,查询A服务的日志,收到的结果是:2018-11-05 02:56:09,比预期小了8个小时。

  • 于是在A服务中restTemplate.postForObject()方法debug代码,发现使用的是jackson序列化方式,继续debug定位发现jackson的配置信息类JacksonAutoConfiguration。

JacksonAutoConfiguration设置时区的代码如下:

            private void configureDateFormat(Jackson2ObjectMapperBuilder builder) {
                // We support a fully qualified class name extending DateFormat or a date
                // pattern string value
                String dateFormat = this.jacksonProperties.getDateFormat();
                if (dateFormat != null) {
                    try {
                        Class<?> dateFormatClass = ClassUtils.forName(dateFormat, null);
                        builder.dateFormat(
                                (DateFormat) BeanUtils.instantiateClass(dateFormatClass));
                    }
                    catch (ClassNotFoundException ex) {
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
                                dateFormat);
                        // Since Jackson 2.6.3 we always need to set a TimeZone (see
                        // gh-4170). If none in our properties fallback to the Jackson's
                        // ***先读取配置文件的时区
                        TimeZone timeZone = this.jacksonProperties.getTimeZone();
                        //***如果配置文件没指定时区,则取下面值
                        if (timeZone == null) {
                            timeZone = new ObjectMapper().getSerializationConfig()
                                    .getTimeZone();
                        }
                        simpleDateFormat.setTimeZone(timeZone);
                        builder.dateFormat(simpleDateFormat);
                    }
                }
            }
  • 跟踪timeZone = new ObjectMapper().getSerializationConfig() .getTimeZone();继续找,在BaseSettings.java发现:
    private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone("UTC");
  • 原来jackson在处理date类型时,如果不指定时区,则会取UTC。

解决办法

在A服务的配置文件application.properties增加配置,指定jackson使用的时区:

#指定时区为东八区
spring.jackson.time-zone=GMT+8

重新打包部署后OK。

相关文章

网友评论

      本文标题:RestTemplate使用jackson序列化的时区问题

      本文链接:https://www.haomeiwen.com/subject/sbtpxqtx.html