<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 64,  comments - 9,  trackbacks - 0

    Motivition

    曾經(jīng)有一個(gè)網(wǎng)友問(wèn)過(guò)我這樣一個(gè)問(wèn)題:
    <%@page contentType="text/html; charset=UTF-8"%>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
    中國(guó)
    </body>
    </html>
    這個(gè)頁(yè)面在為什么在運(yùn)行的時(shí)候“中國(guó)”會(huì)變成亂碼?

    Analysis

          Key Step

    對(duì)于上面問(wèn)題的分析需要從整個(gè)JSP頁(yè)面請(qǐng)求的生命周期來(lái)看,一般的都需要經(jīng)歷下面幾個(gè)階段:
    1。應(yīng)用服務(wù)器根據(jù)JSP頁(yè)面生成一個(gè)Java文件
    2。應(yīng)用服務(wù)器調(diào)用java.exe將Java文件編譯成一個(gè)Servlet對(duì)應(yīng)的class文件
    3。用戶的瀏覽器請(qǐng)求JSP對(duì)應(yīng)的Servlet,Web容器起一個(gè)線程執(zhí)行Servlet,將數(shù)據(jù)返回給客戶端瀏覽器
    4。用戶的IE根據(jù)返回的數(shù)據(jù),將結(jié)果顯示給用戶。

          Key Step Analysis

    為了更好的了解編碼問(wèn)題,我們暫時(shí)先從上面的四個(gè)環(huán)節(jié)一步步來(lái)分析,根據(jù)分析的結(jié)果,來(lái)得到最終的解決辦法。

    1. 在應(yīng)用服務(wù)器根據(jù)JSP頁(yè)面生成Java文件階段。

    應(yīng)用服務(wù)器會(huì)將整個(gè)JSP頁(yè)面的代碼讀取出來(lái),然后寫(xiě)到一個(gè)新的JAVA文件中,在讀文件和寫(xiě)文件的時(shí)候都牽涉到一個(gè)編碼問(wèn)題,這個(gè)編碼問(wèn)題應(yīng)用服務(wù)器是如何解決的呢?我研究Tomcat應(yīng)用服務(wù)器的源代碼,發(fā)現(xiàn)Tomcat中有一個(gè)pageEncoding參數(shù)非常重要,在ParserController會(huì)從JSP文件中讀出這個(gè)參數(shù)(如果沒(méi)有讀到,就從第一行的contentType中讀取charset),然后保存起來(lái),如果沒(méi)有讀取到這個(gè)參數(shù),會(huì)從JspConfig中讀出一個(gè)默認(rèn)的PageEncoding參數(shù),如果這兩個(gè)參數(shù)都沒(méi)有的設(shè)置,系統(tǒng)會(huì)默認(rèn)成ISO8859-1的編碼來(lái)讀取原來(lái)的JSP文件。
       從上面的分析出,我們已經(jīng)基本了解了應(yīng)用服務(wù)器讀取JSP文件的編碼方式,由于Java底層都是基于Unicode編碼來(lái)存儲(chǔ)字符的,所以在寫(xiě)文件的時(shí)候,都輸出成Unicode編碼的形式。
    2。在JDK將Java文件編譯成Class文件的時(shí)候
    可以利用-encoding參數(shù)指定源文件的編碼,這在手動(dòng)編譯的時(shí)候非常重要,因?yàn)檫@決定了Java虛擬機(jī)讀取Java文件時(shí)采用的編碼方式,但是在Web應(yīng)用中這個(gè)環(huán)節(jié)我們可以忽略,因?yàn)閼?yīng)用服務(wù)器可以很好的解決這個(gè)編碼。以Tomcat為例,由于生成的java文件是固定的UTF-8編碼,所以Tomcat也固定的采用UTF-8編碼來(lái)讀取,通過(guò)瀏覽AbstractCatalinaTask可以看到reader = new InputStreamReader(hconn.getInputStream(), CHARSET);其中的CHARSET=utf-8。所以在這個(gè)環(huán)節(jié)中應(yīng)用服務(wù)器都可以很好的把握,不會(huì)帶來(lái)編碼問(wèn)題。

    3. 用戶的瀏覽器請(qǐng)求JSP對(duì)應(yīng)的Servlet階段。

    如果前面的環(huán)節(jié)中不會(huì)帶來(lái)編碼問(wèn)題,也就是說(shuō)在Java虛擬機(jī)中運(yùn)行的時(shí)候,能正常的獲取到“中國(guó)”,那么在執(zhí)行servlet的環(huán)節(jié)中不會(huì)“中國(guó)”始終是以Unicode存儲(chǔ)的中國(guó),那么在第三個(gè)環(huán)節(jié)中需要關(guān)注的是JspWriter如何將數(shù)據(jù)返回給客戶端瀏覽器。大家可以試驗(yàn)一下,在java中如果用new String(str.getBytes("encoding"),"encoding")執(zhí)行的時(shí)候,始終不會(huì)出現(xiàn)亂碼問(wèn)題,也就是說(shuō),一個(gè)字符串可以用不同的代碼來(lái)getBytes()生成字節(jié)數(shù)組(底層I18N.jar所作的工作,提供Byte2Char和Char2Byte的轉(zhuǎn)換)。
       如果大家可以理解這一點(diǎn),那么下面大家就需要了解JspWriter輸出字符串時(shí)采用的編碼方式是什么?通過(guò)瀏覽Response.java類可以了解到Tomcat應(yīng)用服務(wù)器是根據(jù)contentType來(lái)獲取的writer的編碼方式,也就是說(shuō),最后返回客戶端的字節(jié)流是contentType對(duì)應(yīng)的charset中獲取出來(lái)的字節(jié)數(shù)組。

    4. IE根據(jù)返回的數(shù)據(jù)處理顯示階段

    通過(guò)前面的分析可以了解到,應(yīng)用服務(wù)器返回的“中國(guó)”是根據(jù)ContentType中的charset來(lái)顯示的,只要IE知道該用這個(gè)編碼來(lái)接收字節(jié)流并轉(zhuǎn)成字符串,并將用戶的瀏覽器推薦合適的編碼來(lái)查看結(jié)果,用戶就可以瀏覽到正確的“中國(guó)”兩個(gè)字。可以高興得是,目前的IE等瀏覽器正式這樣處理的。

    Conclusion

    通過(guò)上面的分析,我們可以看到,在整個(gè)JSP頁(yè)面的編碼過(guò)程中,我們真正要解決的是JSP文件到Java文件這個(gè)過(guò)程中的編碼問(wèn)題,也就是PageEncoding參數(shù)的設(shè)置問(wèn)題。由于pageEncoding參數(shù)是servlet2.3規(guī)范中規(guī)定的參數(shù),所以下面的方法在很多應(yīng)用服務(wù)器下面都通用,這方面的設(shè)置本人在工作中基本上得到了下面的一些方法:
    1。在JSP頁(yè)面的中加上pageEncoding參數(shù),比如:<%@ page contentType="text/html; charset=UTF-8" pageEncoding="GBK"%>,這樣就可以將頁(yè)面可以用ANSI來(lái)存儲(chǔ)。也就是說(shuō)當(dāng)頁(yè)面存儲(chǔ)的編碼方式和chtentType中的charset不一樣的時(shí)候,可以考慮加上pageEncoding參數(shù)。
    2。有些應(yīng)用服務(wù)器(如weblogic),在沒(méi)有獲取到pageEncoding參數(shù)的時(shí)候,不是先從charset中獲取編碼類型,而是從另外的一些配置文件,如weblogic.xml文件中加上下面的代碼:
    <jsp-descriptor>
         <jsp-param>
              <param-name>compilerSupports</param-name>
              <param-value>true</param-value>
         </jsp-param>
         <jsp-param>
              <param-name>encoding</param-name>
              <param-value>GBK</param-value>
         </jsp-param>
    </jsp-descriptor>
    (在Tomcat5X種也有類似的處理,在應(yīng)用的web.xml文件中加上類似下面的配置項(xiàng))
    </jsp-config>
    <jsp-property-group>
               <url-pattern>*.jsp</url-pattern>
               <el-ignored>true</el-ignored>
    </jsp-property-group>
    </jsp-config>

     

    以上是對(duì)JSP頁(yè)面編碼的一些分析和處理方法,希望能對(duì)大家今后的學(xué)習(xí)和工作中有幫助!

    posted on 2009-07-23 14:41 super_nini 閱讀(345) 評(píng)論(0)  編輯  收藏

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    <2009年7月>
    2829301234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

    常用鏈接

    留言簿

    隨筆檔案

    文章檔案

    相冊(cè)

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 亚洲人精品午夜射精日韩| 成人免费无码大片A毛片抽搐色欲| 成人永久福利免费观看| 亚洲综合中文字幕无线码| 69影院毛片免费观看视频在线| 亚洲av无码一区二区三区网站| 国精产品一区一区三区免费视频| 亚洲综合色婷婷七月丁香| 大地资源网高清在线观看免费| 中文字幕亚洲图片| 国产午夜精品久久久久免费视| 亚洲国产一区视频| 美女无遮挡拍拍拍免费视频 | 男男AV纯肉无码免费播放无码| 亚洲午夜国产精品| 久久电影网午夜鲁丝片免费| 亚洲狠狠婷婷综合久久蜜芽| 国产成人无码区免费A∨视频网站| 在线精品自拍亚洲第一区| vvvv99日韩精品亚洲| 国产乱子伦精品免费视频| 国精无码欧精品亚洲一区| 亚洲香蕉免费有线视频| 亚洲欧洲日产国码久在线| 亚洲国产91精品无码专区| 国产精品免费大片一区二区| 亚洲高清视频在线观看| 无码日韩精品一区二区免费| 日韩色视频一区二区三区亚洲| 亚洲男女内射在线播放| 少妇无码一区二区三区免费| 亚洲www77777| 久久国产成人精品国产成人亚洲| 成全高清在线观看免费| 亚洲综合久久一本伊伊区| 免费看小12萝裸体视频国产| 免费91麻豆精品国产自产在线观看| 亚洲不卡1卡2卡三卡2021麻豆| 永久免费毛片手机版在线看| 91福利免费网站在线观看| 亚洲AV无码一区二区三区在线|