異常
場景:接口正常的項目在上線的時候關閉swagger2。
問題:使用自定義實體類返回數據的接口會出現如下異常:
原因分析
項目配置
項目中有這樣的配置類:
class MyWebConfig extends WebMvcConfigurationSupport
類中有如下代碼:
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
super.configureMessageConverters(converters);
//解決中文亂碼
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
//添加 stringHttpMessageConverter
converters.add(stringHttpMessageConverter);
}
這個配置的初衷是解決直接返回String的接口中文亂碼的問題(StringHttpMessageConverter的默認編碼是ISO-8859-1)
問題的關鍵就在於這個重寫的方法。
爲什麼swagger2開啓時正常?
在未關閉swagger2之前接口正常,是因爲swagger處理了converters,接口正常。
關閉swagger2之後,configureMessageConverters方法會導致默認的converts無法初始化。
注意:關於swagger是如何處理的此處不做分析。
通過WebMvcConfigurationSupport源碼分析
WebMvcConfigurationSupport類中的代碼片段:
protected final List<HttpMessageConverter<?>> getMessageConverters() {
if (this.messageConverters == null) {
this.messageConverters = new ArrayList();
this.configureMessageConverters(this.messageConverters);
if (this.messageConverters.isEmpty()) {
this.addDefaultHttpMessageConverters(this.messageConverters);
}
this.extendMessageConverters(this.messageConverters);
}
return this.messageConverters;
}
項目中重寫了configureMessageConverters方法並addconverters會導致
this.ddDefaultHttpMessageConverters(this.messageConverters)方法不執行。
從而導致默認的converts無法添加到messageConverters中,這就是異常得原因。
解決辦法
註釋掉重寫configureMessageConverters的代碼
重寫方法extendMessageConverters
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
}
更改StringHttpMessageConverter的默認編碼
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
super.extendMessageConverters(converters);
for (HttpMessageConverter<?> converter : converters) {
if (converter instanceof StringHttpMessageConverter) {
StringHttpMessageConverter stringHttpMessageConverter = (StringHttpMessageConverter) converter;
stringHttpMessageConverter.setDefaultCharset(StandardCharsets.UTF_8);
}
}
}
這樣修改之後,返回String中文沒有亂碼問題,返回實體的接口也正常了。