- 簡介
- 在Java項目的開發過程中,經常會出現中文亂碼的情況,這也是一直是困擾大家的一個問題,很多的程式員都會經常遇到這個問題。
- 有時搗鼓調試半天也摸不著頭緒,不知道究竟哪裡出了問題,那是你還不清楚出現這種亂碼的原由。
- 下面為大家簡單介紹一下有關常見的Java中文亂碼以及相應的解決方案,讓我們在以後的開發中再遇到亂碼知道怎麼處理,對症下藥。
- J2EE程式分析
- 從事Java的人都知道Java項目是由容器管理(Tomcat)來管理的,項目中的各類檔案如JSP/Servlet/JAVA/CLASS的初始化、對象建立、回收、編譯、運行等都是由容器來統一管理,因此,在Java內部可以由容器來統一設定字元集編碼方式,這樣Java本身的編碼即可統一,而亂碼往往不是出現在內部,而是Java在與外界互動、打交道的過程中,由於內外字元集編碼方式不一樣才導致的亂碼,那麼Tomcat主要與哪些外部互動呢?
- 在上面說了可以通過設定容器的編碼方式改變Java的編碼,那麼在沒有
部署到容器中之前怎麼編碼,它的各種運算中只要涉及到編碼問題都會自動轉化為unicode編碼,而在沒有轉化為unicode之前是採用作業系統的預設編碼,這也是Java可以跨平台的一個原因。
- 與Java進行直接互動的往往是瀏覽器、資料庫等,Java的輸入、輸出也是和它們打交道,統一Java系統的輸入、輸出編碼方式是解決亂碼問題的原理。
- 中文亂碼產生原因以及解決
- Java、JSP檔案編譯
- 首先Java(包括JSP)源檔案中很可能包含有中文,而Java和JSP源檔案的儲存方式是基於位元組流的,如果Java和JSP編譯成class檔案過程中,使用的編碼方式與源檔案的編碼不一致,就會出現亂碼。
- 解決方案(常用)
<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%>
- Java與其它軟體互動
- Java同瀏覽器、資料庫、檔案、頁面等傳遞資料時,需要發生位元組與字元之間得轉換,Java字元與其它位元組之間相互轉換,如果在以上轉換過程中使用的編碼方式與位元組原有的編碼不一致,很可能就會出現亂碼。
- JSP與頁面參數之間的亂碼
- 擷取頁面參數時一般採用系統預設的編碼方式,如果頁面參數的編碼類別型和系統預設的編碼類別型不一致,很可能就會出現亂碼。解決這類亂碼問題的基本方法是在頁面擷取參數之前,強制指定request擷取參數的編碼方式:
request.setCharacterEncoding("GB18030")
- 如果在JSP將變數輸出到頁面時出現了亂碼,可以通過設定
- 代碼
response.setContentType("text/html;charset=GBK")
- 如果我們的JSP檔案過多,一個一個的設定是很麻煩的,則我們可以在設定檔裡面設定,如下:
<!--過濾器配置--> <filter> <filter-name>CharSetEncodingFilter</filter-name> <filter-class>com.bjpowernode.drp.util.filter.CharSetEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>GB18030</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharSetEncodingFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CharSetEncodingFilter</filter-name> <url-pattern>/servlet/*</url-pattern> </filter-mapping>
3.在DRP中,從Servlet往JSP傳參的過程中始終出現亂碼,利用URLEncoder.encode(),編碼後仍出現亂碼,代碼如下:
a.在Servlet中利用Response.sendRedirect()進行重新導向
//重新導向到物料首頁 response.sendRedirect(request.getContextPath()+"/basedata/item_maint.jsp?
errorMessage="+java.net.URLEncoder.encode(message,"GB18030"));
b.JSP中接受參數
將字元轉為位元組
new String(request.getParameter("errorMessage").getBytes("8859_1"),"GB18030")
- Java與資料庫之間的亂碼
- 大部分資料庫都支援以unicode編碼方式,所以解決Java與資料庫之間的亂碼問題比較明智的方式是直接使用unicode編碼與資料庫互動。
- Java與檔案/流之間的亂碼
- Java讀寫檔案最常用的類是FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream和FileOutputStream是基於位元組流的,常用於讀寫二進位檔案。讀寫字元檔案建議使用基於字元的FileReader和FileWriter,省去了位元組與字元之間的轉換。但這兩個類的建構函式預設使用系統的編碼方式,如果檔案內容與系統編碼方式不一致,可能會出現亂碼。
- InputStreamReader/OutputStreamWriter,它們也是基於字元的,但在建構函式中可以指定編碼類別型
InputStreamReader(InputStream in, Charset cs) 和OutputStreamWriter(OutputStream out, Charset cs)。
iiv. 總結
- 只有知道問題產生的原因,才能很快找到解決方案,出現了問題不是簡單的從網上找找怎麼做,然後,按照別人說的步驟進行簡單設定設定,就把遇到的問題弄好了,如果不知道原因,等下次出現的時候,雖然還是同樣的問題,你也照樣不會,只是按著別人說的去做,去模仿永遠是別人的東西,如果想變成自己的,就要自己去做。