Springboot2.x配置ObjectMapper日期格式化不生效

问题起因:与前端对接接口发现日期时间输出格式是数组,而代码中又有ObjectMapper格式化日期配置

环境:springboot2.x+jdk1.8

相关代码配置类

复制代码
@Configuration
public class JacksonConfig {
    @Primary
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        //省略LocalDate、LocalTime的配置
        objectMapper.registerModule(javaTimeModule);
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        objectMapper.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        objectMapper.registerModule(javaTimeModule);
        return objectMapper;
    }
}

@EnableWebMvc
@Component
public class MyWebMvcConfig implements WebMvcConfigurer {
     //省略一些常用配置
}

问题排查思路:

  1. 使用自动注入ObjectMapper,查看bean配置是否生效,bebug结果显示配置是注入到bean中
  2. 通过调用栈debug到AbstractJackson2HttpMessageConverter类,发现与注入的ObjectMapper的配置不一致
    private ObjectMapper selectObjectMapper(Class<?> targetType, @Nullable MediaType targetMediaType)
  3. 搜索发现代码注入@EnableWebMvc。将注解注释后重新bebug发现配置生效了。

解决方案:

方案一:直接删除@EnableWebMvc注解重启生效

方案二:保持原代码不动,在实现WebMvcConfigurer的类中重写extendMessageConverters方法

复制代码
@Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter<?> converter : converters) {
            if (converter instanceof MappingJackson2HttpMessageConverter) {
                ((MappingJackson2HttpMessageConverter) converter).setObjectMapper(objectMapper);
                break;
            }
        }
    }

方案三:在LocalDateTime、LocalDate、LocalTime等字段使用@JsonFormat,如果接受参数类型也是日期时间类型,建议也加上@DateTimeFormat

因为是接手别人的代码,线上已经运行,没有办法只有选择方案二、方案三