rocketmq-spring-boot-starter踩坑记录(一)springboot时间格式化失效问题

1,836 阅读4分钟

问题描述

事情是这样的,今天开发的时候突然发现接口返回的时间字段全部变成时间戳了(实际应为yyyy-MM-dd HH:mm:ss格式)

有问题的数据: createTime: 1616592460000
正常的数据: createTime: "2021-03-24 21:27:40"

问题排查

1.配置检查

看到问题第一反应就是,开发的时候错把时间格式化的配置删掉了。立马检查了下。诶

---application.properties

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

关键的配置都在呀,那是啥问题呢?!?

image.png

2.版本对比

然鹅,就这点小问题能难住受过九年义务教育de我?既然之前版本是没问题的,那就找找之前的版本比对一哈

image.png

接着我上测试环境溜一眼,果然。上个版本牟门提

createTime: "2021-03-24 21:27:40"

image.png

既然之前代码没问题,那肯定是后续开发中提交的版本中有一个出问题了
顺着git提交记录,确定了最可能出问题的几个提交记录,checkout,运行程序
终于找到运行后出现createTime: 1616592460000的版本

3.程序员的字典Google

找了出问题的版本代码,然鹅,配置没毛病,阿这image.png

---application.properties

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

那我只能...

image.png

解决方案(一)

在原本的配置下加上spring.jackson.serialization.write-dates-as-timestamps=false

注:

  • 第1行设置格式
  • 第2行设置时区
  • 第3行表示不返回时间戳,如果为 true 返回时间戳,如果这三行同时存在,以第3行为准即返回时间戳
#日期格式化
spring.jackson.date-format=yyyy-MM-dd
spring.jackson.time-zone=GMT+8
spring.jackson.serialization.write-dates-as-timestamps=false

然鹅,没有效果image.png

解决方案(二)

看看自己的代码有没有因为添加拦截器创建了一个配置类,该类继承了WebMvcConfigurationSupport
就是这个逼!以前是用 WebMvcConfigurerAdapter ,springboot 2.0 建议使用 WebMvcConfigurationSupport
但是在添加拦截器并继承 WebMvcConfigurationSupport 后会覆盖@EnableAutoConfiguration关于WebMvcAutoConfiguration的配置!从而导致所有的Date返回都变成时间戳
可以采用另外一种方式,在你继承WebMvcConfigurationSupport的子类中添加日期转换的bean

 @Configuration
public class Configurer extends WebMvcConfigurationSupport{
    
    @Autowired
    HttpInterceptor httpInterceptor;
    
    //定义时间格式转换器
    @Bean
    public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        converter.setObjectMapper(mapper);
        return converter;
    }

    //添加转换器
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        //将我们定义的时间格式转换器添加到转换器列表中,
        //这样jackson格式化时候但凡遇到Date类型就会转换成我们定义的格式
        converters.add(jackson2HttpMessageConverter());
    }

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        // TODO Auto-generated method stub
        registry.addInterceptor(httpInterceptor).addPathPatterns("/**");
        super.addInterceptors(registry);
    }   
}

或者可以实现WebMvcConfigurer接口

@Configuration
public class DateFormatForJson implements WebMvcConfigurer {
    /**
     * 使用此方法, 以下 spring-boot: jackson时间格式化 配置 将会失效
     * spring.jackson.time-zone=GMT+8
     * spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
     * 原因: 会覆盖 @EnableAutoConfiguration 关于 WebMvcAutoConfiguration 的配置
     * */
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = converter.getObjectMapper();
        // 生成JSON时,将所有Long转换成String
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        // 时间格式化
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        // 设置格式化内容
        converter.setObjectMapper(objectMapper);
        converters.add(0, converter);
    }
}

不要问我为什么方案二看着眼熟,那是我抄别人博客的image.png

参考地址:cloud.tencent.com/developer/a…
参考地址:blog.csdn.net/qq_24484911…

然鹅,这种方式我并不想用,怕影响底层代码和其他业务,于是根据方案二描述的问题原因,我开始排查出现这个问题的点。

解决方案(三)

排查了一圈,idea(ctrl+shift+f),并未找到新加的拦截器。

image.png

这可咋整?那我只能出大招了呀。既然是加代码出现的问题,那就删代码呗,删掉哪部分代码后问题不出现了那就找到问题所在了吗

image.png

于是经过一系列排查,终于发现.....是这个哔哔哔(此处消音)

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
    <version>2.0.4</version>
</dependency>

引入rocketmq包导致的(应该是包里拦截器影响的,我就没深究扒代码了)
那我能咋说嘛(哔哔哔哔哔哔),算了,解决问题先,上git看看该项目版本更新没

仓库地址:github.com/apache/rock…

一看版本更新了,好家伙,也不知道这个问题缺陷修复了没有。更新了再说

image.png

升级版本,修改坐标版本为<version>2.2.0</version>

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>

刷新maven,重启项目

返回结果

createTime: "2021-03-24 21:27:40"

诶~解决

image.png