SpringMvc @ResponseBody字符串中文亂碼原因及解決方案


今天突然發現一個問題,后來在網上也找到了很多解決思路,自己也查找到了問題所在,記錄一下。

     @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的響應頭,沒有指定字符集的情況下就采用默認的字符集

image

 

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

image

 

二.解決方案中為啥要這么一句? <property name="writeAcceptCharset" value="false"/>

刪除這句配置,注意這樣一行響應頭 Accpet-Charset,復制下來發現竟然有上千個字符和字母,響應信息達到2KB

image

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

image

說明:本來SpringMvc<mvc:annotation-driven/>默認替我們注冊的StringHttpMessageConverter的writeAcceptCharset就是false的,當writeAcceptCharset為true,意思就是寫回服務器上所有可用字符集;

但是我還沒怎么見過響應頭寫回Accpet-charset的,感覺不到有什么作用.

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM