今天突然發現一個問題,后來在網上也找到了很多解決思路,自己也查找到了問題所在,記錄一下。
@RequestMapping(value = "/demo1")
@ResponseBody
public String demo1(){
return "我是中文測試";
}
就是這樣一個簡單的方法,直接返回字符串, 但是在界面上就發現中文亂碼了,配置文件中<mvc:annotation-driven/>的形式開啟的.
其實這個,也不涉及到Json字符串的亂碼問題,因為沒有使用到json的HttpMessageConverter.
解決方案一:
<mvc:annotation-driven conversion-service="conversionService">
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="defaultCharset" value="UTF-8"/>
<property name="writeAcceptCharset" value="false"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
說明:替換其中的StringHttpMessageConverter,它是用來將String寫到response中;
修改的兩個屬性說明:defaultCharset改為UTF-8(項目字符集)即可正確顯示中文,因為默認是ISO-8859-1格式;
writeAcceptCharset修改為false,即可看到響應頭清爽很多,節省資源;
解決方案二:
@RequestMapping(value = "/demo1",produces = {"text/plain;charset=utf-8","text/html;charset=utf-8"})
@ResponseBody
public String demo1(){
return "我是中文測試";
}
說明:指定響應的字符集為utf-8,就不會再用StringHttpMessageConverter的字符集了;
解決方案三:
@RequestMapping(value = "/demo1",produces = {"application/json;charset=utf-8"})
@ResponseBody
public String demo1() throws JsonProcessingException {
return new ObjectMapper().writeValueAsString("我是中文測試");
}
說明:自己轉換成JSON寫回客戶端,因為返回值類型還是寫的String,所以仍然使用的是StringHttpMessageConverter,但是return “我是中文測試” ; 這個返回值不是JSON類型的,客戶端無法解析(即使指定了produces也沒用);所以需要我們手動轉換成JSON格式字符串,這樣客戶端接收到的就是JSON格式的響應了.
比較說明:
解決方案一、二返回給瀏覽器的類型都是text/plain或 text/html類型的文本,而解決方案三返回的是application/json類型,但是返回結果也不是JSON,所以在我看來三種方式區別都不大吧。
問題原因出在哪兒?
一.StringHttpMessageConverter往客戶端寫回字符串時先添加Content-Type的響應頭,沒有指定字符集的情況下就采用默認的字符集

未指定的情況下字符集默認為ISO-8859-1格式的字符串,所以中文字符串就亂碼了

二.解決方案中為啥要這么一句? <property name="writeAcceptCharset" value="false"/>
刪除這句配置,注意這樣一行響應頭 Accpet-Charset,復制下來發現竟然有上千個字符和字母,響應信息達到2KB

添加上<property name="writeAcceptCharset" value="false"/>之后,只需要142個字節(1KB=1024字節)

說明:本來SpringMvc<mvc:annotation-driven/>默認替我們注冊的StringHttpMessageConverter的writeAcceptCharset就是false的,當writeAcceptCharset為true,意思就是寫回服務器上所有可用字符集;
但是我還沒怎么見過響應頭寫回Accpet-charset的,感覺不到有什么作用.

