Java中文亂碼問題的徹底解決方案__安卓

來源:互聯網
上載者:User

     自從接觸Java和JSP以來,就不斷與Java的中文亂碼問題打交道,現在終於得到了徹底的解決,現將我們的解決心得與大家共用。

一、Java中文問題的由來

Java的核心和class檔案是基於unicode的,這使Java程式具有良好的跨平台性,但也帶來了一些中文亂碼問題的麻煩。原因主要有兩方面,Java和JSP檔案本身編譯時間產生的亂碼問題和Java程式於其他媒介互動產生的亂碼問題。

首先Java(包括JSP)源檔案中很可能包含有中文,而Java和JSP源檔案的儲存方式是基於位元組流的,如果Java和JSP編譯成class檔案過程中,使用的編碼方式與源檔案的編碼不一致,就會出現亂碼。基於這種亂碼,建議在Java檔案中盡量不要寫中文(注釋部分不參與編譯,寫中文沒關係),如果必須寫的話,盡量手動帶參數-ecoding GBK或-ecoding gb2312編譯;對於JSP,在檔案頭加上或基本上就能解決這類亂碼問題。

本文要重點討論的是第二類亂碼,即Java程式與其他儲存媒介互動時產生的亂碼。很多儲存媒介,如資料庫,檔案,流等的儲存方式都是基於位元組流的,Java程式與這些媒介互動時就會發生字元(char)與位元組(byte)之間的轉換,具體情況如下:

從頁面form提交資料到java程式 byte->char
從java程式到頁面顯示 char?>byte

從資料庫到java程式 byte?>char
從java程式到資料庫 char?>byte

從檔案到java程式 byte->char
從java程式到檔案 char->byte

從流到java程式 byte->char
從java程式到流 char->byte

如果在以上轉換過程中使用的編碼方式與位元組原有的編碼不一致,很可能就會出現亂碼。

二、解決方案

前面已經提到了Java程式與其他媒介互動時字元和位元組的轉換過程,如果這些轉換過程中容易產生亂碼。解決這些亂碼問題的關鍵在於確保轉換時使用的編碼方式與位元組原有的編碼方式保持一致,下面分別論述(Java或JSP自身產生的亂碼請參看第一部分)。

1、JSP與頁面參數之間的亂碼
JSP擷取頁面參數時一般採用系統預設的編碼方式,如果頁面參數的編碼類別型和系統預設的編碼類別型不一致,很可能就會出現亂碼。解決這類亂碼問題的基本方法是在頁面擷取參數之前,強制指定request擷取參數的編碼方式:request.setCharacterEncoding("GBK")或request.setCharacterEncoding("gb2312")。
如果在JSP將變數輸出到頁面時出現了亂碼,可以通過設定response.setContentType("text/html;charset=GBK")或response.setContentType("text/html;charset=gb2312")解決。
如果不想在每個檔案裡都寫這樣兩句話,更簡潔的辦法是使用Servlet規範中的過慮器指定編碼,過濾器的在web.xml中的典型配置和主要代碼如下:
web.xml:


CharacterEncodingFilter
net.vschool.web.CharacterEncodingFilter
encodingGBK

 

CharacterEncodingFilter
/*


CharacterEncodingFilter.java:

public class CharacterEncodingFilter implements Filter
{

protected String encoding = null;

public void init(FilterConfig filterConfig) throws ServletException
{
this.encoding = filterConfig.getInitParameter("encoding");
}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
request.setCharacterEncoding(encoding);
response.setContentType("text/html;charset="+encoding);
chain.doFilter(request, response);
}

}


2、Java與資料庫之間的亂碼
大部分資料庫都支援以unicode編碼方式,所以解決Java與資料庫之間的亂碼問題比較明智的方式是直接使用unicode編碼與資料庫互動。很多資料庫驅動自動支援unicode,如Microsoft的SQLServer驅動。其他大部分資料庫驅動,可以在驅動的url參數中指定,如如mm的mysql驅動:jdbc:mysql://localhost/WEBCLDB?useUnicode=true&characterEncoding=GBK。

3、Java與檔案/流之間的亂碼
Java讀寫檔案最常用的類是FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream和FileOutputStream是基於位元組流的,常用於讀寫二進位檔案。讀寫字元檔案建議使用基於字元的FileReader和FileWriter,省去了位元組與字元之間的轉換。但這兩個類的建構函式預設使用系統的編碼方式,如果檔案內容與系統編碼方式不一致,可能會出現亂碼。在這種情況下,建議使用FileReader和FileWriter的父類:InputStreamReader/OutputStreamWriter,它們也是基於字元的,但在建構函式中可以指定編碼類別型:InputStreamReader(InputStream in, Charset cs) 和OutputStreamWriter(OutputStream out, Charset cs)。

4、其他
上面提到的方法應該能解決大部分亂碼問題,如果在其他地方還出現亂碼,可能需要手動修改代碼。解決Java亂碼問題的關鍵在於在位元組與字元的轉換過程中,你必須知道原來位元組或轉換後的位元組的編碼方式,轉換時採用的編碼必須與這個編碼方式保持一致。我們以前使用Resin伺服器,使用smartUpload組件上傳檔案,上傳檔案同時傳遞的中文參數擷取沒有亂碼問題。當在Linux中把Resin設定成服務後,上傳檔案同時的中文參數擷取出現了亂碼。這個問題困擾了我們很久,後來我們分析smartUpload組件的源檔案,因為檔案上傳採用的是位元組流的方式,裡麵包含的參數名稱和值也是位元組流的方式傳遞的。smartUpload組件讀取位元組流後再將參數名稱和值從位元組流中解析出來,問題就出現在smartUpload將位元組流轉換成字串時採用了系統預設的編碼,而將Resin設定成服務後,系統預設的編碼可能發生了改變,因此出現了亂碼。後來,我們更改了smartUpload的源檔案,增加了一個屬性charset和setCharset(String)方法,將upload()方法中提取參數語句:
String value = new String(m_binArray, m_startData, (m_endData - m_startData) + 1 );
改成了
String value = new String(m_binArray, m_startData, (m_endData - m_startData) + 1, charset );
終於解決了這個亂碼問題。

三、後記
接觸Java和JSP已經有一年多了,這一年來最大的收穫是越來越喜歡上了Java,開始把問題當作樂事去研究,沒有了以前的恐懼心理,我相信我會繼續堅持下去。這一年來,從網上學習了很多同行的寶貴經驗,在此表示感謝。這是我第一篇自己總結的Java學習心得,由於水平有限,本文中偏頗和錯誤之處,歡迎指正。如果對你有些價值,在保留作者資訊和文章原始出處的前提下可以隨處轉載。
撰寫該文之前已參考了很多關於Java中文問題的文章,其中影響比較大的有owen1944在“Java研究組織”中發表的《這是我們公司總結的一些關於中文亂碼問題的一些解決方案和經驗和大家分享。》等。本文談到的解決方案已應用到“基於網路的協作學習系統-WebCL”等項目中,並通過資源綁定的方式實現了該平台中文文兩個版本的即時轉換。Google根據瀏覽器自動選擇語言,一個頁面同時顯示多種語言的國際化應用和車東的《Java中文處理學習筆記??Hello Unicode》一文引起了我極大的興趣,日後想將繼續探討Java的國際化問題,歡迎大家一起討論。

相關文章

聯繫我們

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