Servlet&JSP的那些事兒(二十二)

來源:互聯網
上載者:User

本篇的主題是中文亂碼問題.我們將分析中文亂碼產生的原因,並通過多種方式解決中文亂碼問題。

在電腦中,只有位元據。不管資料儲存在記憶體或者外存,對於我們看到的字元,也是以二進位形式儲存的。不同字元對應位元的規則,就是字元的編碼。字元編碼的集合就稱之為字元集。

常用字元集

常用的字元集有ASCII碼,ISO8859-1,GB2312,GBK,Unicode,UTF-8。每一個ASCII碼用8位位元表示,比如字元“0”表示為48。ASCII最多能表示256種字元,最初只用於表示英文字母和其他字元,但是隨著電腦發展與普及,其他國家都需要引入本地語言,所以明顯不夠用。ISO8859-1則擴充了ASCII碼,增加了一些其他的西文字元。GB2312是中國國家標準漢字資訊交換用編碼,GBK對GB2312提供擴充支援,除了完全相容GB2312外,還支援繁體字,不常用漢字和許多符號。不過GBK並不是國家標準,它只是規範。

每個國家都定義了自己的字元集。如果你發送一封郵件給一個德國朋友,郵件發送時按照漢字編碼轉換為位元據,等到他接收到以後再將位元據轉換為德文,那就會出現亂碼。因為,在不同的字元集之間,同一個數字可能對應了不同的符號,也可能在另一種字元集中,沒有對應的符號。為瞭解決這些問題,Unicode協會制定了Unicode編碼。unicode使用雙位元組無符號數對每一個字元進行編碼。範圍為0-65535,目前已定義了40000多個不同的unicode字元。UTF-8是為了減少儲存和傳輸英文字元的資料量。因為unicode編碼一個字元要佔兩個位元組,而在網路上,大多數資訊是用英文表示的。

對亂碼產生原因的分析

為了讓使用java編寫的程式能在各種語言平台下運行,java在內部使用unicode字元集來表示字元,這樣就存在unicode字元集和本地字元集進行轉換的過程。在java中讀取本地字元資料時,需要將其轉換為unicode編碼,而在輸出時,需要將unicode編碼轉換為本地字元編碼。例如在中文系統中從控制台讀取一個字元“中”,實際上讀取的是它的GBK編碼0xD6D0,在java語言中藥將GBK轉換為unicode編碼0x4E2D,此時,記憶體中儲存的字元“中”對應的數值為0x4E2D,在向控制台輸出時,則將其轉換為GBK。

根據上述過程,轉換過程是可逆的,不應該存在亂碼問題才對。但實際上,web應用中,瀏覽器,web伺服器,web應用程式,資料庫中都可能使用不同的字元集,從而導致字元在各種不同字元之間轉換時,出現亂碼問題。

當從unicode字元集向某個字元集轉換時,如果該字元集沒有對應的編碼,則得到0x3f(即問號?)。從其他字元集向unicode編碼轉換時,如果這個位元在該字元集中沒有標識任何字元,則得到的結果是0xfffd。

中文亂碼問題解決方案

以post方法提交的表單資料中有中文字元

由於web容器預設採用ISO-8859-1編碼,在servlet/jsp中,通過請求對象的getParameter()方法得到的字串是以ISO-8859-1轉換而來,這是導致亂碼的原因之一,為了避免容器以ISO-8859-1的編碼格式返回字串,對於以POST方法提交的表單資料,可以在擷取請求參數前,調用request.setCharacterEncoding("GBK") ,明確指出請求本文使用的編碼格式是GBK,在向瀏覽器發送資料前,調用指定輸出內容的編碼方式是GBK。

對於JSP頁面,在擷取請求參數值前,寫上下面的代碼:

<%request.setCharacterEncoding("gb2312");%>

為了指定輸出內容的編碼格式,設定page指令的contentType屬性。

<%reponse.setContentType("text/html;charset=GBK");%>

在web容器轉換jsp頁面後的servlet類中,會自動添加下面的代碼:

reponse.setContentType("text/html;charset=GBK");

以get方式提交的表單資料有中文字元

當提交表單採用get方式時,提交的資料作為查詢字串被附加到URL的末端,發送到伺服器,此時在伺服器端調用setCharacterEncoding就沒用了,我們需要在得到請求參數的值後,自己做正確的編碼轉換。

String name = request.getParameter("name");name = new String(name.getBytes("ISO-8859-1","GBK"));

在資料庫中儲存的讀取中文資料

要解決讀取資料庫中中文資料出現亂碼的問題,只需要將資料庫預設的編碼格式改為GBK或GB2312即可。

使用過濾器解決中文亂碼問題

過濾器代碼如下:

package com.shan.filter;import java.io.IOException;import javax.servlet.*;public class EncodingFilter implements Filter {private String encoding = null;private FilterConfig filterConfig = null;public void init(FilterConfig filterConfig) throws ServletException {this.filterConfig = filterConfig;this.encoding = filterConfig.getInitParameter("encoding");}public void destroy() {this.encoding = null;this.filterConfig = null;}public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {if(null != encoding){request.setCharacterEncoding(encoding);}chain.doFilter(request, response);}}

web.xml設定檔內容如下:

<?xml version="1.0" encoding="ISO-8859-1"?><web-app xmlns="http://java.sun.com/xml/ns/javaee"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  version="3.0"  metadata-complete="true">  <filter>    <filter-name>EncodingFilter</filter-name>    <filter-class>com.shan.filter.EncodingFilter</filter-class>    <init-param>      <param-name>encoding</param-name>      <param-value>gb2312</param-value>    </init-param>  </filter>  <filter-mapping>    <filter-name>EncodingFilter</filter-name>    <url-pattern>/*</url-pattern>  </filter-mapping></web-app>

讓Tomcat支援中文檔案名稱

在web應用程式中我們可能會使用具有中文檔案名稱的檔案,然而Tomcat在預設情況下不能訪問中文檔案名稱的檔案。為了讓Tomcat可以正常訪問,需要配置在Tomcat安裝目錄下的conf檔案夾下的server.xml檔案。找到<Connector>元素,在該元素中添加URIEncoding屬性,將其值設定為UTF-8,如下所示:

<Connector port="8080" protocol="HTTP/1.1"               connectionTimeout="20000"               redirectPort="8443" URIEncoding="UTF-8"/>

絕大多數瀏覽器在傳輸URI時都以UTF-8編碼。在web應用程式中,如果調用response.sendRedirect()方法重新導向到中文檔案名稱的頁面,需要用如下方式調用:

response.sendRedirect(java.net.URLEncoder.encode("中文檔案.html","UTF-8"));

除此之外,對於其他訪問方式,可直接寫中文檔案名稱,不需要進行編碼。

轉載請註明出處:http://blog.csdn.net/iAm333

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.