项目场景:
springboot项目中,做一个时间格式的配置选项,使用到 WebMvcConfigurer 中的 configureMessageConverters 信息转换器。
遇到了重写的 configureMessageConverters 未生效的问题。
问题描述
我重写的 configureMessageConverters 没有生效,并未按照我的方式序列化。
代码情况如下:
继承后重写configureMessageConverters
//只包含了部分重要代码
@Configuration
public class MvcConfiguration extends BaseWebConfiguration {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
JavaTimeModule module = new JavaTimeModule();
// 序列化器
module.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
// 反序列化器
// 这里添加的是自定义的反序列化器
module.addDeserializer(LocalDateTime.class,
new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
ObjectMapper objectMapper = new ObjectMapper();
SimpleDateFormat smt = new SimpleDateFormat("yyyy-MM--dd HH:mm:ss");
objectMapper.setDateFormat(smt);
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
objectMapper.registerModule(module);
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
converters.add(mappingJackson2HttpMessageConverter);
}
}
原因分析:
当时找了很久的原因,最后在添加转换器这步骤发现问题。
我在重写后,new MappingJackson2HttpMessageConverter(),是以列表形式添加在后面的。
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
converters.add(mappingJackson2HttpMessageConverter);
通过打断点可以发现,List<HttpMessageConverter<?>> converters 集合前面已经内置的有很多转换器了,其中就有MappingJackson2HttpMessageConverter。
失效的原因是springboot前面已经注册一个MappingJackson2HttpMessageConverter.class bean,它会作为此类型中的默认httpMessageConvert, 而我们自己写的那个写的MappingJackson2HttpMessageConverter是添加再列表后面。在做序列化处理时当有一个convert满足后,方法就直接返回了不会再交给下一个convert处理,因此之前自己写的convert并不能起作用。也就出现失效的情况。
解决方案:
第一种解决方案,在添加操作时改为指定位置的插入:
//将自己重新的添加在最前面
add(0, 自己的转换器)
例如:
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
//添加在队列最前面
converters.add(0, mappingJackson2HttpMessageConverter);
问题得已解决
第二种解决方案是:直接修改springboot最先注册的MappingJackson2HttpMessageConverter 中使用到的ObjectMapper。
总结:
官方推荐直接实现WebMvcConfigurer或者直接继承WebMvcConfigurationSupport,方式一实现WebMvcConfigurer接口(推荐),方式二继承WebMvcConfigurationSupport类。
今日遇到这类问题我也是顺路做个记录。