spring 在处理http请求将对象转成json的过程 默认是使用jackson 工具处理的。jackson同样提供了 一套注解设置转成json的格式。如JsonFormat,JsonProperty,JsonIgnore,JsonIgnoreProperties等等这样方面我们开发的注解。但是有时候我们加上这些注解的时候却不生效,达不到我们想要的效果。造成这样的原因很多。其中一个原因是由于spring默认的转换json的jackson被替换造成。
1, 首先了解几个核心的类:
HttpMessageConverters:spring消息转换管理器 管理消息转换器 用户可以自定义消息转换器但必须要放在这个转换器中
HttpMessageConverter:spring提供的消息转换接口
MappingJackson2HttpMessageConverter :spring基于jackson对HttpMessageConverter的实现 springboot是通过JacksonHttpMessageConvertersConfiguration这个类对 MappingJackson2HttpMessageConverter进行自动加载的。以下附有springboot的HttpMessageConvertersAutoConfiguration 部分代码:
@Configuration
@ConditionalOnClass(HttpMessageConverter.class)
@AutoConfigureAfter({ GsonAutoConfiguration.class, JacksonAutoConfiguration.class })
@Import({ JacksonHttpMessageConvertersConfiguration.class,
GsonHttpMessageConvertersConfiguration.class })
public class HttpMessageConvertersAutoConfiguration {
static final String PREFERRED_MAPPER_PROPERTY = "spring.http.converters.preferred-json-mapper";
private final List<HttpMessageConverter<?>> converters;
public HttpMessageConvertersAutoConfiguration(
ObjectProvider<List<HttpMessageConverter<?>>> convertersProvider) {
this.converters = convertersProvider.getIfAvailable();
}
@Bean
@ConditionalOnMissingBean
public HttpMessageConverters messageConverters() {
return new HttpMessageConverters(this.converters == null
? Collections.<HttpMessageConverter<?>>emptyList() : this.converters);
}
}
FastJsonHttpMessageConverter4:阿里的fastjson对HttpMessageConverter的实现 。
2, 设置fastjson作为默认的消息解析器
@Bean
public HttpMessageConverters fastJsonConfigure() {
FastJsonHttpMessageConverter4 converter = new FastJsonHttpMessageConverter4();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect);
fastJsonConfig.setCharset(StandardCharsets.UTF_8);
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
converter.setFastJsonConfig(fastJsonConfig);
converter.setDefaultCharset(StandardCharsets.UTF_8);
return new HttpMessageConverters(converter);
}
3,手动设置jackson作为解析器(当查找不到问题的时候 可手动设置避免jackjson注解不生效)
@Bean
@Primary
@ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder){
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.setDateFormat(DateFormat.getDateTimeInstance());
return objectMapper;
}
@Bean
@Primary
@ConditionalOnBean(ObjectMapper.class)
public HttpMessageConverters JacksonConverters(ObjectMapper objectMapper){
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter
= new MappingJackson2HttpMessageConverter();
jackson2HttpMessageConverter.setObjectMapper(objectMapper);
return new HttpMessageConverters(jackson2HttpMessageConverter);
}
4,排查jackson注解不生效:可从spring容器中获取HttpMessageConverters 查看converters属性对应的值。
HttpMessageConverters converters = context.getBean(HttpMessageConverters.class);