如何處理中文亂碼問題

在Java編程中,經常會碰到漢字的處理及顯示問題,以不小心就會產生一大堆亂碼或者問號。造成這種問題的根本原因是Java中默認的編碼方式是Unicode,而中國人通常使用的文件和DB都是基於GB2312或BIG5等編碼,故會出現此問題。
       對於不同的問題,不同的JDK版本,不同的應用服務器(如Tomcat,Jboss,Weblogic),處理方法都會有一些微小的差異。在這裏,主要針對Tomcat中JSP開發容易出現的中文亂碼問題進行討論,一般有以下幾種情況:

      1.JSP中輸出中文的亂碼問題

       所謂在JSP輸出中文,即直接在JSP中輸出中文,或者給變量賦中文值再輸出等,這種情況下的亂碼問題往往是因爲沒有給JSP頁面制定顯示字符的編碼方式,解決問題如下:

       ·在JSP頁面頭部加上語句<%@ page contentType="text/html;charset=gbk"%>(在Servlet頁面中使用

httpServletResponse.setContentType("text/html;charset=gbk")),最好同時在JSP頁面的head部分加上<meta http-equiv="Content-Type" content="text/html;charset=gbk">

       ·在每次要輸出中文的地方主動轉換編碼方式,比如要在頁面中輸入“中文”二字,就可以用以下方式:

<%
       String str
="中文";
      
byte[] tmpbyte=str.getBtyes("ISO-8859-1");
       str
=new String(tmpbyte);
       out.print(str);
%>


       2.獲取表單提交的數據時的中文亂碼問題

       在沒有加任何其他處理之前,用request.getParameter(panamName)獲取表單提交中的數據,且表單數據中含有中文時,返回的字符串會出現亂碼。出現這種問題的原因是Tomcat的J2EE實現對錶單提交,即以POST方式提交的參數採用默認的ISO-8859-1來處理。
       比如,建立一個test.jsp,內容爲:

<%@ page contentTyp="text/html;charset=gbk"%>
<%
       String str
=request.getParameter("chStr");
      
if(str==null) str="沒有輸入值";
%>
<html>
   
<head>
      
<title>中文Test</title>
      
<meta http-equiv="Content-Type" content="text/html;charset=gbk">
      
<meta http-equiv=param content=no-cache>
   
</head>
   
<body>你輸入的內容爲:<%=str%><br>
      
<form action="test.jsp" method="post">
       請輸入中文:
<input type="text" name="chStr">
      
<input type="submit" value="確定">
      
</form>
   
</body>
</html>


       運行過後,在輸入框中輸入漢字“中文”,提交過後再顯示出來後就變成了一堆亂碼。解決此問題的辦法有兩個。一是不修改其他設置,只是在將表單中的中文數據取出來過後再轉換編碼,方法如語句String str=request.getParameter("chStr");String str=new String(sre.getByte("ISO-8859-1"),"gbk"),但這種方法只是從一個局部來考慮問題,如果這樣的地方太多,就不得不將這條語句重複寫很多次,在比較大的項目中,這是一種不太可行的方案。另一個方法就是讓對所有頁面的請求都通過一個Filter,將處理字符集設置爲gbk。具體的做法如下(在Tomcat的webapps/servlet-examples目錄有一個完整的例子,也可以參考其中web.xml和SetCharacter EncodingFilter的配置):

       首先將%TOMCAT%/webapps/servlets-examples/Web-INF/classes/filters/目錄下的文件SetCharacterEncodingFilter.class拷貝到自己應用的/Web-INF/classes/com/util/filter目錄下;然後再在web.xml文件的<web-app>後面加上如下配置代碼:

<filter>
     
<filter-name>Set Character Encoding</filter-name>
     
<filter-class>com.ccut.struts.SetCharacterEncodingFilter</filter-class>
     
<init-param>
        
<param-name>encoding</param-name>
        
<param-value>gbk</param-value>
     
</init-param>
</filter>
<filter-mapping>
     
<filter-name>Set Character Encoding</filter-name>
     
<url-pattern>/*<url-pattern>
    </filter-mapping>


      3.URL中的中文問題

       對於直接通過在URL中傳遞中文參數,如“http://localhost/a.jsp?str=中文”這樣的get請求,在服務端用request.getParameter("name")時返回的往往是亂碼。按以上的做法設置Filter沒有用,用request.setCharacterEncoding("gbk")的方式,仍然不管用。
             例如,建立test2.jsp文件,內容爲:

<%@ page contentTyp="text/html;charset=gbk"%>
<%
       String str
=request.getParameter("chStr");
      
if(str==null) str="沒有輸入值";
%>
<html>
      
<head>
         
<title>中文Test</title>
         
<meta http-equiv="Content-Type" content="text/html;charset=gbk">
         
<meta http-equiv=param content=no-cache>
      
</head>
      
<body>你輸入的內容爲:<%=str%><br>
      
<form action="test.jsp" method="post">
         
<a href="test2.jsp?chStr=中文">點擊這裏提交中文參數</a>
      
</form>
      
</body>
</html>

       運行後,可見通過URL傳遞的中文參數取出來過後變成了亂碼,造成這種結果的原因是Tomcat中以get方式提交的請求對query-string處理時採用了和post方法不一樣的處理方式。
       解決這個問題的方法是打開Tomcat安裝目錄下的/conf/server.xml文件,找到Connector塊,往其中添加URIEncoding="gbk",添加過後完整的Connector塊代碼如下:

<Connector port="8080"               
maxThreads
="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
    debug="0" connectionTimeout="20000"
    disableUploadTimeout="true"
    URIEncoding="gbk"
    />


      4.數據庫訪問時的亂碼問題

       在建立數據庫時,將數據庫中的所有表的編碼方式都設置爲gbk,原因是JSP中也使用了gbk編碼,這樣統一的結果是可以減少很多不必要的編碼轉換問題。另外,在使用JDBC連接MySQL數據庫時,連接字符串寫成如下形式可以避免一些中文問題:

jdbc://mysql://hostname:port/DBname?user=username&
password=pwd&
useUnicode
=True&
characterEncoding
=gbk

       如果是以數據源的方式連接數據庫,在配置文件中使用:
<parameter>
<name>url</name>
<value>
jdbc://mysql://hostname:port/DBname?
&useUnicode=True&characterEncoding=gbk
</value>
</parameter>

       但是,如果使用一個已經存在的數據庫,數據庫的編碼方式是ISO-8859-1,而Web應用中使用UTF-8,且數據庫中已經有很多重要信息,因此不能通過更改數據庫的編碼方式來解決問題。這個時候,在往數據庫中寫數據庫時,一定要在JDBC連接字符串中加入“useUnicode=True&characterEncoding=ISO-8859-1”,這樣可以順利的往數據庫中寫入正常的數據。但是,在將數據讀出數據庫時,亂碼又會出現,這個時候就應該在數據取出時對其轉碼,可以將轉碼功能寫爲一個函數,具體實現如下:
public String charConvert(String src){
       String result
=null;
   
if(src!=null){
   
try{
          result
=new String(src.getBytes("ISO=8859-1"),"gbk");
       }
catch(Exception e)
   
{
             result
=null;
             }

       }

      
return result;
}
       於是,在從數據庫讀出數據過後調用charConvert(rs.getString("colName")),這樣就可以正常顯示數據庫中的中文數據了。 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章