開始接觸使用springmvc的時候, 返回controller 內容中文亂碼。html
百度一下,而後配置 messageConverters 加上 java
<bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"/> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>text/plain; charset=UTF-8</value> </list> </property> </bean>
即解決了中文亂碼。web
假設咱們不加上 json 數據的消息處理spring
好比 json
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" >
那麼 若是 controller 返回 對象或者json 對象確定會報錯:HttpMediaTypeNotAcceptableException: Could not find acceptable representationmvc
由於 沒有 對應消息處理器 處理該返回值,MediaType 類型返回的 contenType 類型確定是 application/jsonapp
StringHttpMessageConverter 處理返回的 contenType 是 text 或者 plain 編碼
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:126) at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:90) at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:189) at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:69) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
在 messageConverters 加上 <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" > debug
便可解決了,也就是 controller 能夠直接 返回對象 了。日誌
就是這樣解決了問題。其實不太明白這樣配置的意思。
解惑
StringHttpMessageConverter
StringHttpMessageConverter 只能對 controller 的 返回 string 類型的內容進行 處理,
若是是其餘的對象, 甚至是 controller 返回的 int 類型, spirngmvc 也不會使用 StringHttpMessageConverter 對返回的內容進行處理的。
會將 StringHttpMessageConverter 忽略掉,若是沒有 消息處理器對這個返回結果進行處理,那麼就會 拋出 :
HttpMediaTypeNotAcceptableException: Could not find acceptable representation 異常
那麼爲何 不配置 StringHttpMessageConverter 會致使中文亂碼?
由於 查看一下 StringHttpMessageConverter 源碼能夠知道, StringHttpMessageConverter 默認的編碼
public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
使用了這個,若是不配置指定 ISO-8859-1 確定中文亂碼了。
而 StringHttpMessageConverter 有一個 構造方法,容許指定 編碼
所以
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
便可 解決中文亂碼。
即supportedMediaTypes 配置不指定 編碼也是不會中文亂碼的
<bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"/> <property name="supportedMediaTypes"> <list> <value>text/plain</value> <value>text/html</value> </list> </property> </bean>
若是 這樣配置訪問 controller 返回string 類型的 方法
就能夠經過 debug 日誌看到 例如 :
RequestResponseBodyMethodProcessor.writeWithMessageConverters(150) | Written [{"a":"aa哈哈"}] as "text/html" using [org.springframework.http.converter.StringHttpMessageConverter@20c2
而 這時候
這時候的響應給客戶端的響應頭 Content-Type 確定是
Content-Type:text/html;charset=UTF-8
也就是說
supportedMediaTypes 配置的是 StringHttpMessageConverter 響應給客戶端的 Content-Type 內容。
這個 StringHttpMessageConverter 源碼裏面,默認的 supportedMediaTypes 就是 text和 plain
即 <value>text/html</value>
<value>text/plain</value>
其實 這個 supportedMediaTypes 咱們能夠配置不少種類型的
好比 配置 <value>application/json;charset=UTF-8</value>
springmvc 將 儘可能 根據內容 儘可能使用 對應的 ,正確的 Content-Type
好比 只配置了 <value>application/json;charset=UTF-8</value>
那麼 Content-Type 就是 application/json;charset=UTF-8
是不會 報錯的。
第二 種解決中文亂碼
StringHttpMessageConverter 配置 構造方法沒有指定 字符集而是 supportedMediaTypes 指定字符集
<property name="supportedMediaTypes"> <list> <value>text/plain; charset=UTF-8</value> <value>text/html; charset=UTF-8</value> </list> </property>
那麼 StringHttpMessageConverter 就會根據 supportedMediaTypes 裏面的 charset 來使用 響應的字符集,
也就是 這樣也是能夠防止亂碼的。
第三 返回json 對象或者對象不亂碼?
好比配置了
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" >
</bean>
也就是 說將使用其處理 全部的類型,
假如沒有配置 StringHttpMessageConverter
那麼 string類型的返回controller 方法 最終也是會使用 MappingJacksonHttpMessageConverter 進行處理的,
只是 contentype 將是 application/json;charset=UTF-8
若是配置 StringHttpMessageConverter 了,那麼string類型的 返回方法將使用 StringHttpMessageConverter 來處理,
從 名字就能夠看出來了。
MappingJacksonHttpMessageConverter 處理過的 響應頭部都是 application/json;charset=UTF-8
由於
MappingJacksonHttpMessageConverter 源碼默認指定了 默認字符集 UTF-8因此咱們配置的時候不須要指定 字符集了,不會亂碼的