springboot中的resttemplate使用了jackson序列化遇到的坑

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

springboot之restTemplate学习

SpringBoot系列: RestTemplate 快速入门 - harrychinese - 博客园 (cnblogs.com)

由于springboot默认使用jackson做序列化,但是jackson序列化按照的是GMT时区的时间。中国是GTM+8小时,所以原本在中国是2020-11-28 19:00:00,序列化到前端就是2020-11-28 12:00:00

就是说北京时间晚上19点的时候,伦敦才中午12点。

解决返回前端的日期字段少了8小时,可以通过入下三种方式,

一:所有日期字段加上时区

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

二:springboot配置文件中统一配置

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

三:通过配置类的方式:

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

前端的展示时间的问题解决了,但是后端的问题并没有解决,一次偶然中发现,微服务consumer调用微服务provider的时候,传过去的时间也少了8个小时。

排查后发现使用springboot的RestTemplate请求去调用服务的时候,也会进行jackson序列化,此时上面三种方式,二和三都失效了,序列化的时候都不会帮我们+8小时,

只有在每个字段上面加上时区标识才有效

timezone = "GMT+8"

调式看为什么RestTemplate的时候序列化少8小时

 代码调式到这里的时候,值变了

com.fasterxml.jackson.databind.ObjectWriter#writeValue(com.fasterxml.jackson.core.JsonGenerator, java.lang.Object)

最后跟到这里来了。java.text.SimpleDateFormat#format(java.util.Date, java.lang.StringBuffer, java.text.Format.FieldDelegate)

最关键的日期字段格式化在这里

g.writeString(f.format(value));

DateFormat里面的属性如下:

 calendar里面的时区,使用的是UTC(相当于GMT+0)

 

原文地址:https://www.cnblogs.com/mkl34367803/p/14053637.html