java 亂碼解決

來源:互聯網
上載者:User

jsp頁面的編碼方式有兩個地方需要設定: 

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 

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

其中:pageEncoding 指的是jsp檔案本身在本地儲存時的編碼方式。contentType的charset是指伺服器發送網頁內容給用戶端時所使用的編碼。 

從第一次訪問一個jsp頁面開始,到這個頁面被發送到用戶端,這個Jsp頁面要經過三次編碼轉換: 

第一階段是jsp編譯成.java,它會根據pageEncoding的設定讀取jsp,結果是由指定的編碼方案翻譯成統一的UTF-8 JAVA源碼(即.java),如果pageEncoding設定錯了,或沒有設定,出來的就是中文亂碼。 

第二階段是由JAVAC的JAVA源碼至java byteCode的編譯,不論JSP編寫時候用的是什麼編碼方案,經過這個階段的結果全部是UTF-8的encoding的java源碼。 

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")

get傳值或者url亂碼時,手動設定接收的參數String str = new String(request.getParameter("something").getBytes("ISO-8859-1"),"utf-8") ;

由上可見get,post傳值在tomcat5中是不一樣的

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.