问题
想要自定义一个序列化,将long型转成string,将double类型保留3位小数。但是发现配置后无效。
代码
@Configuration
public class BaseMvcConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
/**
* 序列换成Json时,将所有的Long变成String
* 因为js中得数字类型不能包括所有的java Long值
*/
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
// 所有的double类型返回保留三位小数
simpleModule.addSerializer(Double.class, CustomerDoubleSerialize.instance);
simpleModule.addSerializer(Double.TYPE, CustomerDoubleSerialize.instance);
objectMapper.registerModule(simpleModule);
jackson2HttpMessageConverter.setObjectMapper(objectMapper);
converters.add(jackson2HttpMessageConverter);
}
修改
如下修改代码或者继承WebMvcConfigurationSupport问题解决,但是如果继承的方式会导致有配置类无效,详细可看WebMvcAutoConfiguration类。
@Configuration
public class BaseMvcConfig implements WebMvcConfigurer, InitializingBean {
@Autowired(required = false)
private ObjectMapper obj;
private SimpleModule getSimpleModule() {
/**
* 序列换成Json时,将所有的Long变成String
* 因为js中得数字类型不能包括所有的java Long值
*/
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
// 所有的double类型返回保留三位小数
simpleModule.addSerializer(Double.class, CustomerDoubleSerialize.instance);
simpleModule.addSerializer(Double.TYPE, CustomerDoubleSerialize.instance);
return simpleModule;
}
@Override
public void afterPropertiesSet() throws Exception {
if (obj != null) {
SimpleModule simpleModule = getSimpleModule();
obj.registerModule(simpleModule);
}
}
原因
失效的原因是springboot本也页会注册一个MappingJackson2HttpMessageConverter.class bean,它会作为此类型中的默认httpMessageConvert, 而我们自己写的那个写的MappingJackson2HttpMessageConverter是添加再列表后面。而对于返回值重写RequestResponseBodyMethodProcessor方法中对@ResponseBody处理时当有一个convert满足重写后,方法就直接返回了不会再交给下一个convert处理,因此之前自己写的convert并不能起作用。
所以直接修改springboot注册的MappingJackson2HttpMessageConverter 会使用到的ObjectMapper,或者自己注册一个MappingJackson2HttpMessageConverter bean达到我们的目的。