这是一次帮别人排错记录,自己也没这样用过,所以记录下
错误使用示例
@Configuration
public class CustomWebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
super.configureMessageConverters(converters);
converters.add(mappingJackson2HttpMessageConverter());
}
// 解决序列化空对象问题
private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
ObjectMapper mapper = new ObjectMapper();
// 关键代码
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
return new MappingJackson2HttpMessageConverter(mapper);
}
自定义WebMvcConfigurer示例
@Configuration
public class SuperCodeWebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthenticationInterceptor()).addPathPatterns("/**");
}
}
这样使用,启动服务后发现拦截器不生效,压根没有执行SuperCodeWebMvcConfig.addInterceptors方法
最后看了下源码,默认的WebMvcConfigurationSupport 这个啥也没干
然后翻看自动配置的WebMvcAutoConfiguration中用的是EnableWebMvcConfiguration
DelegatingWebMvcConfiguration通过setConfigurers,把其他的自定义的WebMvcConfigurer收集起来,然后在addInterceptors里面遍历所有WebMvcConfigurer执行addInterceptors
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
// 忽略其他代码
@Override
protected void addInterceptors(InterceptorRegistry registry) {
this.configurers.addInterceptors(registry);
}
// 忽略其他代码
}
class WebMvcConfigurerComposite implements WebMvcConfigurer {
private final List<WebMvcConfigurer> delegates = new ArrayList<>();
public void addWebMvcConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.delegates.addAll(configurers);
}
}
// 忽略其他代码
@Override
public void addInterceptors(InterceptorRegistry registry) {
for (WebMvcConfigurer delegate : this.delegates) {
delegate.addInterceptors(registry);
}
}
// 忽略其他代码
}
结论: 不推荐直接继承WebMvcConfigurationSupport ,使用默认配置EnableWebMvcConfiguration即可,如果一定要这样用,可继承EnableWebMvcConfiguration/DelegatingWebMvcConfiguration
添加自定义拦截器,消息转换器推荐实现WebMvcConfigurer接口方式
最后如果只是要自定义HttpMessageConverter
@Configuration
public class HttpMessageConvertersConfig {
// /**
// * 使用Jackson序列化web返回结果
// * @return
// */
// @Bean
// MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
// ObjectMapper mapper = new ObjectMapper();
// // 关键代码
// mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// return new MappingJackson2HttpMessageConverter(mapper);
// }
/**
* 使用fastjson序列化web返回结果
* @return
*/
@Bean
public HttpMessageConverters fastJsonHttpMessageConverters() {
// 1. 需要定义一个converter转换消息的对象
FastJsonHttpMessageConverter fasHttpMessageConverter = new FastJsonHttpMessageConverter();
// 2. 添加fastjson的配置信息,比如:是否需要格式化返回的json的数据
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(JsonUtil.getFEATURES());
// 3. 在converter中添加配置信息
fasHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
fastJsonConfig.setCharset(Charset.forName("UTF-8"));
// 中文乱码解决方案
List<MediaType> mediaTypes = new ArrayList<>();
//设定json格式且编码为UTF-8
mediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
fasHttpMessageConverter.setSupportedMediaTypes(mediaTypes);
HttpMessageConverter<?> converter = fasHttpMessageConverter;
return new HttpMessageConverters(converter);
}
}