springmvc 配置 messageConverters 和解決中文亂碼 和 HttpMediaTypeNotAcceptableException

開始接觸使用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因此咱們配置的時候不須要指定 字符集了,不會亂碼的

相關文章
相關標籤/搜索