javaWeb開發中的中文編碼問題

常規解決亂碼問題的方法是:java

   a.把全部的jsp頁面的charset設置爲UTF-8。
   b.添加過濾器,在filter內調用request.setCharacterEncoding("utf-8")方法將request的字符集設定爲utf-8。
    <filter> 
       <filter-name>CharacterEncoding</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>CharacterEncoding</filter-name> 
       <url-pattern>*.action</url-pattern> 
    </filter-mapping>
   c.Tomcat(或jboss)的URIEncoding默認是ISO-8859-1,須要設置爲UTF-8。
     tomcat目錄下......\conf\server.xml文件中
      <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"/>
      加上 URIEncoding="UTF-8"
      <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8"/>
   以上方法全用上基本上能夠解決一些廣泛問題
  
   在實際的應用當中,主要會有如下四種使用方法:
   一、表單的get提交
   二、表單的post提交
   三、頁面連接傳遞中文參數
   四、地址欄中參數直接輸入中文提交(直接在ie或firefox中敲上中文進行訪問)
   在分析解決以上的幾種狀況前,首先咱們先了解一下,一個url請求並響應的流程
   瀏覽器 IE/FireFox ----------->Servlet容器------------------------>顯示頁面
       編碼          使用容器的URIEncoding轉碼       根據頁面的編碼設置進行解碼
  
   1.表單get方式提交
      瀏覽器根據頁面的charset編碼方式對頁面進行編碼,而後提交至服務器。首先,進入對應的字符編碼過濾器(若是有的話),不過,Tomcat6.0,對於 get提交方式採用的是server.xml文件中的URIEncoding編碼方式,而並不會採用過濾器中設置的編碼,那麼,根據個人環境設置,jsp頁面都使用UTF-8的編碼,Servlet容器的URIEncoding也設置爲UTF-8,則servlet不用進行轉碼便可正確解碼,得到正常的中文 字符串。那麼,響應頁面的中文由於頁面的統一編碼(UTF-8)天然也會正常顯示。固然,若是咱們的Tomcat的URIEncoding設置爲其餘,非UTF-8的編碼方式時,頁面的內容進入Tomcat解析時,由於Tomcat和頁面的編碼不統一,就須要轉碼。
  例如,若是咱們採用Tomcat默認的 ISO-8859-1,那麼當咱們使用request.getParameter("param1")獲取表單參數值時,其實Servlet就進行了轉碼,轉碼過程爲UTF-8-->ISO-58859-1(個人頁面charset都是UTF-8),java僞代碼以下:
  new String(param1.getBytes("UTF-8"), "ISO-8859-1");  web

  new String(變量值.getBytes("UTF-8"),"ISO-8859-1");
  例如表單的username屬性以字符串"編輯"提交,那麼進入容器後,FormBean中的這個變量會亂碼,request.getParameter(username)同樣的效果,s1就是request返回的結果,下面是內存快照。spring

  不過,即便是這樣,咱們依然可使用很是規的方法,取出並顯示出正常的中文,即逆向轉碼,例如上面的亂碼,咱們能夠經過ISO8859-1-->UTF-8轉換一次,還原出正確的中文。
  綜上所述,將Tomcat的URIEncoding設置爲UTF-8(即和頁面的編碼一致便可)就能解決這類狀況,get時,頁面會先按頁面設置的編碼編碼,再提交至web server,顯示時會再根據顯示頁面的編碼進行解碼。瀏覽器

 2.表單的post提交
 對於這種方式的請求,request.setCharacterEncoding(通常來自於web.xml中過濾器設置的參數)方法進行編碼,設置將會產生做用,struts的表單提交方式默認爲post方式,所以,若是都採用UTF-8編碼方式,就不會產生中文亂碼問題。tomcat

3.頁面連接中傳遞中文參數
我虛擬一個這樣的場景,請求頁面中有以下代碼服務器

Html代碼 app

<%
String username = "編輯";
%>
<a href="hello.do?username=<%=username%>">頁面中連接傳遞中文</a>
對於這種方式,咱們須要先將參數使用統一的編碼方式編碼,將編碼後的字符放入連接,這裏我對參數以UTF-8方式編碼,以下jsp

Java代碼 post

<%
String username = java.net.URLEncoder.encode("編輯","UTF-8");
%>
那麼,這樣咱們也不會產生中文亂碼問題,由於,字符串編碼的處理過程:字符串->UTF-8(提交的頁面charset)->UTF-8(web server URIE)->UTF-8(顯示的頁面)。
4.地址欄中參數直接輸入中文提交測試

考慮如下場景,在瀏覽器地址欄中直接輸入"http://localhost:8080/helloapp.do?username=編輯"提交,對於這種方式,瀏覽器不會採用頁面的charset方式,也不會按照filter設置的編碼方式。URL中的中文進行編碼後,提交至服務器(IE,FireFox都同樣),而是採用系統的GBK(估計可能和browser的語言版本或設置相關,個人機器上是編碼到GBK)轉碼爲ISO- 8859-1以後,提交至Servlet容器,那麼,若是對於前三種方式咱們所作的設置,此種場景下就不正常了。由於,進入容器時中文進行了GBK至ISO- 8859-1的轉碼,而以前咱們的Servlet容器URIEncoding設置爲UTF-8,當咱們使用 request.getParameter("username")時,至關於又進行了這樣的流程GBK-->ISO- 8859-1-->UTF-8,按照以上咱們使用的測試,那麼就會是亂碼了。此時,若是是使用GBK-->ISO- 8859-1-->GBK的方式轉換,那麼就能正常取出中文漢字。

對於這種狀況,咱們能夠採用的解決辦法就是,Tomcat的URIEncoding採用默認的ISO-8859-1字符集,那麼咱們能夠在程序中經過ISO-8859-1-->GBK這樣的轉碼方式獲得正常的中文「編輯」,但這樣的結果是,咱們get請求方式的中文處理解決辦法,就有問題了。
綜上分析所述,對於亂碼問題,前三種方式是通常用戶的請求方式,第四種屬於非正常途徑的請求方式,對於這種方式產生的問題,可能沒法很好的解決(和瀏覽器有關server端沒法控制)。測試IE6的設置會影響應用路徑的編碼方式,例如地址欄中請求一箇中文JSP頁面,如:http://localhost:8080/helloapp/編輯.jsp,IE默認是勾選"以UTF-8發送 URL"項的,那麼按照我上面總結的處理方式,這個請求能夠正常顯示頁面,如圖:

若是取消IE的這個選項,那麼瀏覽器會以GBK編碼應用路徑的中文,獲得的結果如圖:

按照我上面的設置,若是將Tomcat的URIEncoding設置爲GBK,則也能夠正常顯示頁面。對於FireFox3.0,則是以UTF-8編碼。所以,第四種場景是和客戶端相關。所以,在項目中儘可能避免第4種場景的狀況出現,就基本能夠解決java web開發中的亂碼問題了。

相關文章
相關標籤/搜索