licheng700

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            26 Posts :: 5 Stories :: 5 Comments :: 1 Trackbacks
          Servlet:從源文件到Class的過程

            Servlet源文件是以“.java”結尾的文本文件。本節將討論Servlet的編譯過程并跟蹤其中的中文變化。

            用“javac”編譯Servlet源文件。javac可以帶“-encoding <Compile-charset>”參數,意思是“用< Compile-charset >中指定的編碼來解釋Serlvet源文件”。

            源文件在編譯時,用<Compile-charset>來解釋所有字符,包括中文字符和ASCII字符。然后把字符常量轉變成Unicode字符,最后,把Unicode轉變成UTF。

            在Servlet中,還有一個地方設置輸出流的CharSet。通常在輸出結果前,調用HttpServletResponse的setContentType方法來達到與在JSP中設置<Jsp-charset>一樣的效果,稱之為<Servlet-charset>。

            注意,文中一共提到了三個變量:<Jsp-charset>、<Compile-charset>和<Servlet-charset>。其中,JSP文件只與<Jsp-charset>有關,而<Compile-charset>和<Servlet-charset>只與Servlet有關。

            看下例:

          import javax.servlet.*;

          import javax.servlet.http.*;

          class testServlet extends HttpServlet
          {
           public void doGet(HttpServletRequest req,HttpServletResponse resp)
           throws ServletException,java.io.IOException
           {
            resp.setContentType("text/html; charset=GB2312");
            java.io.PrintWriter out=resp.getWriter();
            out.println("<html>");
            out.println("#中文#");
            out.println("</html>");
           }
          }

            該文件也是用UltraEdit for Windows編寫的,其中的“中文”兩個字保存為“D6 D0 CE C4”(GB2312編碼)。

            開始編譯。下表是<Compile-charset>不同時,CLASS文件中“中文”兩字的十六進制碼。在編譯過程中,<Servlet-charset>不起任何作用。<Servlet-charset>只對CLASS文件的輸出產生影響,實際上是<Servlet-charset>和<Compile-charset>一起,達到與JSP文件中的<Jsp-charset>相同的效果,因為<Jsp-charset>對編譯和CLASS文件的輸出都會產生影響。

            表3 “中文”從Servlet源文件到Class的轉變過程

          Compile-charset Servlet源文件中 Class文件中 等效的Unicode碼
          GB2312 D6 D0 CE C4
          (GB2312)
          E4 B8 AD E6 96 87 (UTF) \u4E2D\u6587 (在Unicode中=“中文”)
          ISO-8859-1 D6 D0 CE C4
          (GB2312)
          C3 96 C3 90 C3 8E C3 84 (UTF) \u00D6 \u00D0 \u00CE \u00C4 (在D6 D0 CE C4前面各加了一個00)
          無(默認) D6 D0 CE C4 (GB2312) 同ISO-8859-1 同ISO-8859-1

            普通Java程序的編譯過程與Servlet完全一樣。

            CLASS文件中的中文表示法是不是昭然若揭了?OK,接下來看看CLASS又是怎樣輸出中文的呢?

            Class:輸出字符串

            上文說過,字符串在內存中表現為Unicode編碼。至于這種Unicode編碼表示了什么,那要看它是從哪種字符集映射過來的,也就是說要看它的祖先。這好比在托運行李時,外觀都是紙箱子,里面裝了什么就要看寄郵件的人實際郵了什么東西。

            看看上面的例子,如果給一串Unicode編碼“00D6 00D0 00CE 00C4”,如果不作轉換,直接用Unicode碼表來對照它時,是四個字符(而且是特殊字符);假如把它與“ISO8859-1”進行映射,則直接去掉前面的“00”即可得到“D6 D0 CE C4”,這是ASCII碼表中的四個字符;而假如把它當作GB2312來進行映射,得到的結果很可能是一大堆亂碼,因為在GB2312中有可能沒有(也有可能有)字符與00D6等字符對應(如果對應不上,將得到0x3f,也就是問號,如果對應上了,由于00D6等字符太靠前,估計也是一些特殊符號,真正的漢字在Unicode中的編碼從4E00開始)。

            各位看到了,同樣的Unicode字符,可以解釋成不同的樣子。當然,這其中有一種是我們期望的結果。以上例而論,“D6 D0 CE C4”應該是我們所想要的,當把“D6 D0 CE C4”輸出到IE中時,用“簡體中文”方式查看,就能看到清楚的“中文”兩個字了。(當然了,如果你一定要用“西歐字符”來看,那也沒辦法,你將得不到任何有何時何地的東西)為什么呢?因為“00D6 00D0 00CE 00C4”本來就是由ISO8859-1轉化過去的。
          posted on 2005-08-13 15:22 小海船 閱讀(88) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 昆山市| 海兴县| 德庆县| 赞皇县| 玛纳斯县| 台湾省| 阳西县| 蛟河市| 澜沧| 皮山县| 老河口市| 连南| 嵊泗县| 邵东县| 洛宁县| 临汾市| 黄石市| 府谷县| 贡山| 石屏县| 富顺县| 定南县| 牡丹江市| 庄河市| 大同县| 紫阳县| 栖霞市| 金秀| 新田县| 平潭县| 沙河市| 确山县| 孝义市| 双牌县| 喀什市| 卓资县| 项城市| 邻水| 靖州| 虹口区| 永丰县|