1. 程式人生 > >淺析SpringMVC POST請求中文亂碼

淺析SpringMVC POST請求中文亂碼

筆者近日遇到了SpringMVC框架POST提交中文亂碼的問題。顯示html特殊字元命名實體(https://www.cnblogs.com/yesw/p/4380442.html)。

對此進行了調查,解決方法在網上有很多,在此進行總結。

在SpringMVC框架下,解決中文提交亂碼的問題,首先要保證頁面設定的form的字元編碼是UTF-8格式。

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>

<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />


其次,Servlet伺服器實現的Servlet遇到URL和POST提交的資料,它會按照指定的字符集解碼。這裡所說的"指定的字符集"是在應用伺服器的配置檔案中配置。對於tomcat伺服器,該檔案是server.xml中的Connector節點指定URIEncoding="UTF-8"。對Get方式的亂碼問題,由於引數是通過URL傳遞的,因此這一設定非常有效。

做到以上兩點,可能仍然不會解決post方式提交的請求的亂碼的問題。原因是Servlet 3.0規範中有關請求資料編碼做了如下解釋:

當前很多瀏覽器並不傳送帶Content-Type頭部的字元編碼識別符號,它會把字元編碼的決定留在讀取HTTP請求的時候。如果客戶端沒有指明編碼,容器用來建立請求讀和解析POST資料的預設編碼必須是"ISO-8859-1"。然而,為了提示開發者客戶端沒有成功傳送一個字元編碼,容器中getCharacterEncoding方法會返回null。
如果客戶端沒有設定字元編碼,並且請求資料使用了不同編碼而不是上述的預設編碼,程式將會出現中斷。為了糾正這種狀態,一個新的方法setCharacterEncoding(String enc) 被新增到ServletRequest介面。開發者呼叫這個方法能重寫容器提供的字元編碼。這個方法必須在解析request中任何post資料或者讀任何輸入之前呼叫。

一旦資料已經被讀取,呼叫這個方法不會影響它的編碼。

再回到springMVC框架,因為框架預設沒有指定按何種字符集對request的內容進行解碼,CharacterEncoding預設為"",所以會發生亂碼問題。

為解決這個問題,當request中的post資料被讀取了的情況下,比如controller層,可以採用

new String(request.getParameter("XXXX").getBytes("iso-8859-1"), "utf-8")的方式進行強制解碼。

或者在request讀取post資料之前,手動設定資料讀取的編碼格式:request.setCharacterEncoding("utf-8");

當然Spring已經提供了現成的編碼過濾器。在Web.xml中增加如下配置(要注意的是它的位置一定要是第一個執行的過濾器,否則可能不會生效)即可:

<filter>
<filter-name>charsetFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>