轉載至:https://www.jianshu.com/p/435c13cfc769
關于spring mvc上傳資料中文亂碼原因:
Servlet 3.0規範中有關請求資料編碼的解釋如下:
目前很多浏覽器并不發送帶Content-Type頭部的字元編碼辨別符,它會把字元編碼的決定留在讀取HTTP請求的時候。如果用戶端沒有指明編碼,容器用來建立請求讀和解析POST資料的預設編碼必須是"ISO-8859-1"。然而,為了提示開發者用戶端沒有成功發送一個字元編碼,容器中getCharacterEncoding方法會傳回null。
如果用戶端沒有設定字元編碼,并且請求資料使用了不同編碼而不是上述的預設編碼,程式将會出現中斷。為了糾正這種狀态,一個新的方法setCharacterEncoding(String enc) 被添加到ServletRequest接口。開發者調用這個方法能重寫容器提供的字元編碼。這個方法必須在解析request中任何post資料或者讀任何輸入之前調用。一旦資料已經被讀取,調用這個方法不會影響它的編碼。
另一種說法:
一、request.setCharacterEncoding():用來確定發往伺服器的參數以漢字的編碼來提取,設定從request中取得的值或從資料庫中取出的值。
指定後可以通過request.getParameter()擷取自己想要的字元串,如果沒有提前指定,則會按照伺服器端預設的“iso-8859- 1”來進行編碼;該方法隻對post請求有效,對get請求無效;對于get請求,應該在server.xml中指定:URIEncoding=utf-8;
注意:在執行request.setCharacterEncoding()之前不能執行request.getParameter()方法;
原因:應該是在執行第一個getParameter()的時候,java将會按照編碼分析所有的送出内容,而後續的getParameter()不再進行分析,是以setCharacterEncoding()無效。而對于GET方法送出表單是,送出的内容在URL中,一開始就已經按照編碼分析送出内容,setCharacterEncoding()自然就無效。
二、response.setCharacterEncoding():設定HTTP 響應的編碼,用于設定伺服器給用戶端的資料的編碼
一般不會用這個方法來設定響應編碼,
一般使用response.setContentType()方法來設定HTTP 響應的編碼,同時指定了浏覽器顯示的編碼;
因為他在執行該方法通知伺服器端以指定編碼進行編碼後,會自動調用response.setCharacterEncoding()方法來通知浏覽器以指定編碼來解碼;使用此方法要在response.getWriter()執行之前或response送出之前;
上傳亂碼解決方式:
一、web.xml
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
<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>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
二、單個字元串轉變
public String utf8coding(String str){
if(TextUtils.isEmpty(str)){
return str;
}
try {
if(str.equals(new String(str.getBytes(),"iso-8859-1").toString())){
return new String(str.getBytes("iso-8859-1"),"utf-8").toString();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return str;
}