JSP中文亂碼的一點研究

來源:互聯網
上載者:User

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

  首先Java(包括JSP)源檔案中很可能包含有中文,而Java和JSP源檔案的儲存方式是基於位元組流的,如果Java和JSP編譯成class檔案過程中,使用的編碼方式與源檔案的編碼不一致,就會出現亂碼。對於JSP,在檔案頭加上或基本上就能解決這類亂碼問題。 我們這篇文章主要是關於JSP頁面部署到Tomcat中的一點研究。

首先我們開啟IDE,這裡我使用的是Eclipse,先建立一個web項目Test,然後在建立一個JSP頁面如下:

<%@ page language="java" pageEncoding="gbk"%><%@ page contentType="text/html;charset=iso8859-1"%><html><head><title>JSP</title><meta http-equiv="Content-Type" content="text/html charset=gb2312"/></head><body>JSP中文亂碼</body></html>

這裡有一點要注意,JSP頁面在儲存的時候也是有編碼的,在Eclipse等IDE中有專門設定檔案編碼的配置,這裡就不在多說。我這裡預設JSP檔案都是以utf-8儲存。

 然後我們將項目部署到Tomcat中,訪問http://localhost:8080/Test/index.jsp, 顯示頁面(index.jsp)就出現亂碼。

 當我們把JSP部署到Tomcat中並啟動並執行話,JSP會經過兩次的“編碼”,第一階段會用pageEncoding,第二階段會用utf-8至utf-8,第三階段就是由Tomcat出來的網頁, 用的是contentType。

 第一階段是jsp編譯成.java,它會根據pageEncoding的設定讀取jsp,結果是由指定的編碼方案翻譯成統一的UTF-8 JAVA源碼(即.java)。

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

 JAVAC用UTF-8的encoding讀取java源碼,編譯成UTF-8 encoding的二進位碼(即.class),這是JVM對常數字串在二進位碼(java encoding)內表達的規範。

 第三階段是Tomcat(或其的application container)載入和執行階段二的來的JAVA二進位碼,輸出的結果,也就是在用戶端見到的,這時參數contentType就發起作用了。

 現在我們來詳細介紹一下上面三個階段:

 第一階段是由jsp編譯成.java,需要讀取源Jsp頁面到記憶體中,然後以某種編碼方式產生Servlet類檔案,這一讀的過程會涉及到採用什麼編碼方式來讀取的問題?如頁面中設定了   pageEncoding="XX",則伺服器在讀取Jsp頁面時,就會使用上面設定的XX來讀取,如果沒有設定,再看是否設定了contentType="text/html; charset=XXX" ,如果設定了,則用charset中指定的編碼方式來讀取。如果這兩個都沒有指定時,則使用預設的編碼方式ISO8859-1來讀取,當把Jsp頁面讀取到記憶體後,在記憶體中以Unicode編碼存在,然後以是使用UTF-8編碼方式來輸出的.java檔案。

下面我們用下面代碼來驗證一下:

String fileName = "D:/Program Files/DevelopMent/Apache Software Foundation/Tomcat 6.0/webapps/ServletTest/index.jsp"; //JSP部署到Tomcat後的位置          PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("d:/index.java"), "UTF-8"));           BufferedReader br = new BufferedReader(new InputStreamReader(                   new FileInputStream(fileName), "gbk"));//jap檔案是以utf-8儲存,所以以gbk來讀取就會產生亂碼         String readContent = null;           while ((readContent = br.readLine()) != null) {               pw.write(readContent+"/r/n");               pw.flush();                        }           pw.close();  

如何你運行以上代碼會產生index.java 檔案,然後我們對比一下Tomcat下真正的.java檔案,該檔案的位置為%TOMCAT_HOME%\work\Catalina\localhost\Test\org\apache\jsp 下,開啟之後你就會發現裡面的漢字亂碼是一樣的,現在大家應該明白第一階段的大致過程了,以及其中編碼的轉換了。

第二階段,我們就不在過多介紹,因為這個階段是JAVA源碼至.class的編譯過程,採用的是UTF-8到UTF-8,轉換之後編碼格式不會發生變化。

第三階段,這裡我們就會用到<%@ page contentType="text/html;charset=iso8859-1"%>,這個時候我們查看第二階段產生的servlet位元組碼,會發現      response.setContentType("text/html;charset=iso8859-1");這句話就是

<%@ page contentType="text/html;charset=iso8859-1"%>被編譯成servlet位元組碼後的樣子。使用者的瀏覽器請求JSP對應的Servlet,Web容器起一個線程執行Servlet,將資料返回給用戶端瀏覽器,以iso8859-1來顯示,以上過程和以下代碼類似:

String fileName = "d:/index.java"; //第一階段產生的檔案          PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("d:/index1.java"), "iso8859-1"));           BufferedReader br = new BufferedReader(new InputStreamReader(                   new FileInputStream(fileName), "utf-8"));           String readContent = null;           while ((readContent = br.readLine()) != null) {              pw.write(readContent+"/r/n");               pw.flush();                        }           pw.close();  

以上就是jsp頁面顯示的整個過程了,僅是個人蔘照網上資料的個人體會,如有不對,請大家指出,謝謝!

相關文章

聯繫我們

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