轉載:http://blog.sina.com.cn/s/blog_5507628e01018p3p.htmlhtml
1.jsp頁面顯示中文亂碼: java
jsp頁面的編碼方式有兩個地方須要設置: 瀏覽器
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> tomcat
<%@ page contentType="text/html;charset=utf-8"%> 服務器
其中:pageEncoding 指的是jsp文件自己在本地保存時的編碼方式。contentType的charset是指服務器發送網頁內容給客戶端時所使用的編碼。 app
從第一次訪問一個jsp頁面開始,到這個頁面被髮送到客戶端,這個Jsp頁面要通過三次編碼轉換: jsp
第一階段是jsp編譯成.java,它會根據pageEncoding的設定讀取jsp,結果是由指定的編碼方案翻譯成統一的UTF-8 JAVA源碼(即.java),若是pageEncoding設定錯了,或沒有設定,出來的就是中文亂碼。 ide
第二階段是由JAVAC的JAVA源碼至java byteCode的編譯,不論JSP編寫時候用的是什麼編碼方案,通過這個階段的結果所有是UTF-8的encoding的java源碼。 post
JAVAC用UTF-8的encoding讀取java源碼,編譯成UTF-8 encoding的二進制碼(即.class),這是JVM對常數字串在二進制碼(java encoding)內表達的規範。 編碼
第三階段是Tomcat(或其的application container)載入和執行階段二的來的JAVA二進制碼,輸出的結果,也就是在客戶端見到的,這時隱藏在階段一和階段二的參數contentType就發揮了功效
因此最終的解決方法爲:
在jsp頁面設置pageEncoding或者contentType的其中一個爲支持中文的編碼格式(如utf-8,gbk,gb2312)。由於設置一個的話,另外一個默認會和它同樣。
若是兩個都設置的話,必須保證兩個都是支持中文編碼(不必定要同樣)。
最佳建議設置以下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page contentType="text/html;charset=utf-8"%>
2. post方式傳值亂碼:
因爲post方式傳值是經過request存儲的,在另外一個頁面也是經過request.getParameter(String name)來提取信息,因此這種狀況下的亂碼主要是由於request存儲信息的編碼設置致使的。post提交時,若是沒有設置提交的編碼格式,則會以iso8859-1方式進行提交,接受的jsp卻以utf-8的方式接受。因此使用以下語句便可獲得單個正確的中文字符串:String str = new String(request.getParameter("something").getBytes("ISO-8859-1"),"utf-8") ;
解決方法:
在接收頁面設置request.setCharacterEncoding("UTF-8")。最好經過過濾器實現每一個頁面都設置爲request.setCharacterEncoding("UTF-8")。
3. get方式傳值亂碼:
get方式傳值有兩種,一種是表單get傳值,另外一種是url地址傳值(實質上這兩種方式都是經過url參數的方式傳值)。
表單方式get傳值:
表單方式get傳值的編碼過程爲,首先瀏覽器根據頁面的charset編碼方式對傳值進行編碼,而後提交至服務器交給tomcat,tomcat對這些信息進行解碼時,採用的解碼方式是由server.xml文件中的URIEncoding設置決定的,也就是說,當咱們使用命令request.getParameter("")獲取表單參數值時,獲得的字符串,通過了charset的編碼和URIEncoding的解碼。
由上所知,只要charset的編碼和URIEncoding的解碼一致,而且支持中文,就能保證沒有亂碼。
設置URIEncoding的方法以下:
方法一:
修改$TOMCAT/conf/server.xml文件,在HTTP Connector或者AJP Connector的配置加上URIEncoding="gbk"
<... maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="gbk" />
方法二:
使用useBodyEncodingForURI="true". 這個方法適合你的TOMCAT實例下須要跑多個不一樣Encoding的程序時。
<... maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" useBodyEncodingForURI="true" />
enableLookups="false" redirectPort="8443" protocol="AJP/1.3" useBodyEncodingForURI="true" />
在Tomcat配置中,鏈接器(HTTP Connector)屬性中有一個URIEncoding和
useBodyEncodingForURI屬性,這兩個屬性設置對URL後的附加參數進行URL解碼時該如何選擇 字符集編碼。URIEncoding用於制定URL後的附加參數的字符集編碼,useBodyEncodingForURI 則說明是否採用實體內容的字符集編碼設置來替代URIEncoding的設置,也就是說當 useBodyEncodingForURI屬性設置爲true時ServletRequest.setCharacterEncoding方法設置的字符集編碼也影響getParameter等方法對URL地址後的參數進行URL解碼的結果。(在/%TomCat_Home%/ conf\server.xml文件中找到 <Connector>標記,而後在後面加上useBodyEncodingForURI=true)
url方式get傳值亂碼:
於這種方式,瀏覽器不會採用頁面的charset方式對URL中的中文進行編碼後提交至服務器(IE,FireFox都同樣),而是採用系統的GBK轉碼爲ISO-8859-1以後提交至服務器tomcat,因此這個過程爲:
首先,url地址中的中文被從gbk轉換成ISO-8859-1,交給tomcat後,又被tomcat根據URLEcoding解碼,這種狀況,只有把URLEcoding設置爲gbk才能在request.getParameter("")時不出現亂碼。可是這樣就會影響到上面的配置,因此一個好的解決方法是,使用java.net.URLEcoder和URLDecoder對地址中的中文進行手動編碼和解碼。
因此一個萬全的解決方法爲:
1.全部頁面的charset設置爲UTF-8。
2.Tomcat的URIEncoding默認是ISO-8859-1,而我設置爲UTF-8,主要是想解決中文命名的文件以及請求以get方式提交有可能出現的亂碼問題。
3.添加過濾器,調用request.setCharacterEncoding("utf-8")方法將request的字符集設定爲utf-8,解決請求以post方式提交的亂碼問題。
4. url地址中存在中文參數時,首先對中文參數使用URLEcoder編碼爲utf-8,而後在request.getParameter("")接收到參數後再使用URLDecoder還原。例如:
From.jsp頁面:
<%String username = "張某某" ;
username = URLEncoder.encode(username,"utf-8");
%>
<a href="to.jsp?param=<%=username %>">轉入</a>
To.jsp頁面
<%=URLDecoder.decode(request.getParameter("param"),"utf-8")%>
總之 ,亂碼的解決方案以下:
post傳值亂碼時,在接收端設置request.setCharacterEncoding("UTF-8");
-- 最好用過濾器設置,而且設置response.setContentType("text/html;charset=utf-8");
get傳值或者url亂碼時,手動設置接收的參數String str = new String(request.getParameter("something").getBytes("ISO-8859-1"),"utf-8") ;
-- 亂碼真糾結。。。。