亂碼緣由:
一、瀏覽器頁面數據傳遞到服務器時亂碼,示意爲:
頁面(字符)------->自動轉換爲字節------->服務器(將字節轉化成字符,不然亂碼)
二、服務器傳遞數據到頁面時亂碼,示意爲:
服務器(字符,須要設置返回數據的中文編碼,不然亂碼)------->自動轉換爲字節------->頁面(將字節按照頁面指定的編碼格式轉化成字符)
詳解以下:
一、瀏覽器頁面數據傳遞到服務器時亂碼
瀏覽器頁面解讀頁面的編碼格式能夠在頁面的頭信息中指定,頁面上的輸入的字符則也是按照指定的編碼格式存儲,傳遞參數的時候會將字符轉化成字節,在後臺就收參數的時候須要將接收到的字節轉化成字符才能操做,可是轉化是默認按照ISO-8859-1的編碼方式轉化的,故會出現亂碼問題.
get請求方式解決:
一、 String userName=new String(request.getParameter("username").getBytes("iso-8859-1 "),"utf-8");
說明:此方法表示在接受參數後從新對參數編碼,故對於get方式要手動對參數逐個解碼,此過程能夠在過濾器中來對參數編碼
二、修改Tomcat的配置,加上URIEncoding="UTF-8" :<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>
注:這種方式缺點顯而易見,換了服務器就要更改,有時候忘記也是很常見的事情,同時這個設置更改了tomcat下全部應用的編碼格式嗎,不夠靈活
post請求方式解決:
一、request.setCharacterEncoding(「utf-8」)
說明:此方法是在接收參數前指定接收數據的編碼格式。
注意:該方法只對post請求中的實體內容有效,對get請求無效,而且轉碼的話前提是頁面指定的編碼格式也要是utf-8,轉碼是按照頁面指定的編碼格式轉換
二、服務器傳遞數據到頁面時亂碼
在服務器向瀏覽器發送數據時會將字符轉化成字節流輸送,可是默認的轉化方式仍是ISO-8859-1,故要指定返回數據的編碼格式。
一、設置響應返回數據格式爲:reponse.setCharacterEncoding(「utf-8」);reponse.setContentType("text/html"),合併寫爲:response.setContentType(「text/html」 ;charset=utf-8)
注:
此方法針對字符流返回數據,由於字符流會按照指定的編碼格式查詢碼錶編碼,可是此方法對於字節流無效,由於字節流不會去查編碼表,返回的數據中若是有中文的話則中文的編碼格式就是中文字符默認的編碼GBK,能夠經過如「hello」.getBytes(「utf-8」)指定字節流的編碼格式;
瀏覽器接收到數據後按照瀏覽器頁面設置的編碼格式來解碼,頁面設置的編碼格式和後臺接受轉碼的編碼格式都要一致才行;
在springMVC中能夠設置以下:
<filter>
<filter-name>characterEncodingFilter</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>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
CharacterEncodingFilter源碼爲:
public class CharacterEncodingFilter extends OncePerRequestFilter {
private String encoding;
private boolean forceEncoding = false;
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public void setForceEncoding(boolean forceEncoding) {
this.forceEncoding = forceEncoding;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
request.setCharacterEncoding(this.encoding);
if (this.forceEncoding) {
response.setCharacterEncoding(this.encoding);
}
}
filterChain.doFilter(request, response);
}
}
當Servlet容器啓動的時候,會讀取web.xml中對於過濾器的配置信息, 讀取到<init-param>中的子標籤<param-name>encoding和forceEncoding所對應的<param-value>的值,再經過調用該類setEncoding(String encoding)和setForceEncoding(boolean forceEncoding) 將值分別注入到encoding和forceEncoding 中。
forceEncoding:字面意思是強制字符集,但你大可沒必要按字面意思理解,由於這個參數的值只不過是指定response的字符集是否也設置成encoding所指定的字符集,因此你能夠選擇設置爲true或false,默認值爲false。
當值爲true時,至關於
request.setCharacterEncoding(this.encoding);
response.setCharacterEncoding(this.encoding);
當值爲false時,至關於:
request.setCharacterEncoding(this.encoding);
故若是在web.xml中設置了此編碼格式就能夠不用再代碼中再寫這兩句設置編碼了