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

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

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

    憨厚生

    ----Java's Slave----
    ***Java's Host***

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      165 隨筆 :: 17 文章 :: 90 評(píng)論 :: 0 Trackbacks

    #

    原文:http://blog.csdn.net/shenzhen_mydream/archive/2008/06/03/2507739.aspx

    亂碼問(wèn)題好像跟我們中國(guó)程序員特別有緣,一直困擾著我們,從開(kāi)始的JSP亂碼問(wèn)題,STRUTS亂碼問(wèn)題,到現(xiàn)在的AJAX亂碼問(wèn)題,無(wú)一不是搞得許多程序員焦頭爛額的,整天罵XXX產(chǎn)品對(duì)中文支持不了,UTF-8無(wú)法使用中文啊什么的,其實(shí)這里面被罵的產(chǎn)品中其實(shí)99%以上是對(duì)中文支持非常好的,而出現(xiàn)亂碼的原因只是因?yàn)樽陨韺?duì)國(guó)際化支持以及文件編碼等信息的認(rèn)識(shí)不知造成的。要知道一個(gè)產(chǎn)品那么流行,怎么可能對(duì)中文支持不了呢,下面就開(kāi)始一一幫大家解決這些問(wèn)題。

    1 、編碼
    -- 想要解決好中文問(wèn)題,對(duì)編碼肯定是不能一概不懂了,編碼是解決中文亂碼問(wèn)題的根本。
    編碼比較常用的有: UTF-8 , GBK , GB2312 , ISO-8859-1 ,除了 iso-8859-1 之外的其它三個(gè)編碼都能很好的支持中文,但它們都兼容 ISO-8859-1 的編碼(就是說(shuō)無(wú)論編碼怎么改變,只要是 ISO-8859-1 中的字符,永遠(yuǎn)不會(huì)出現(xiàn)亂碼)。
    這四種編碼中, GB2312 是中國(guó)規(guī)定的漢字編碼,也可以說(shuō)是簡(jiǎn)體中文的字符集編碼 ; GBK 是 GB2312 的擴(kuò)展 , 除了兼容 GB2312 外,它還能顯示繁體中文,還有日文的假名 ; 而 UTF-8 雖然也支持中文,但卻 與 GB 碼不兼容(編碼值不同) 。 UTF-8 使用的是可變長(zhǎng)的 UNICODE 編碼,編碼可能是 1 位 16 進(jìn)制(即 ISO-8859-1 中的字符,其編碼也是相同的)也有可能是 2 位或 3 位的 16 進(jìn)制。 UTF-8 的優(yōu)點(diǎn)是: 1 、 與 CPU 字節(jié)順序無(wú)關(guān) , 可以在不同平臺(tái)之間交流。 2 、容錯(cuò)能力高 , 任何一個(gè)字節(jié)損壞后 , 最多只會(huì)導(dǎo)致一個(gè)編碼碼位損失 , 不會(huì)鏈鎖錯(cuò)誤 ( 如 GB 碼錯(cuò)一個(gè)字節(jié)就會(huì)整行亂碼 ) ,所以在國(guó)際化處理中基本都是建議使用 UTF-8 作為編碼。

    2、文件的編碼
    --雖然說(shuō)只要設(shè)置了正確的編碼就可以使字符正確顯示了,但如果忽略了文件保存時(shí)的編碼的話,那可是會(huì)讓你走進(jìn)迷霧中的。
    文件編碼最常使用的有兩種:ANSI和UTF-8,光看名字估計(jì)你都可以猜到了,ANSI就是我們保存文件時(shí)使用的默認(rèn)編碼,而UTF-8則需自己設(shè)置。對(duì)于編碼的改變,我使用的工具是NOTEPAD和ECLIPSE,NOTEPAD使用最簡(jiǎn)單,只要打開(kāi)文件后在另存為中選擇相應(yīng)的編碼就行了,而且它對(duì)編碼的支持非常好;而在ECLIPSE中,只要稍微設(shè)置一下就行了,打開(kāi)首選項(xiàng),然后選擇:常規(guī)->內(nèi)容類型(ContentType),在右邊選中你想改變保存編碼的文件類型,然后在下方的缺省編碼中改變其值,最后點(diǎn)擊更新(UPDATE)按鈕即可。


    而在其它的編輯器中,默認(rèn)保存的內(nèi)容都是GB2312或者GBK(NOTEPAD中對(duì)應(yīng)ANSI).而根據(jù)前面所說(shuō)的UTF-8和GBK,GB2312等的編碼值是不同的這一點(diǎn),可以知道,如果文件使用了UTF-8,那么字符編碼就必須使用UTF-8,否則編碼值的不同就可能造成亂碼。而這也就是為什么那么多的人使用了UTF-8編碼后還會(huì)產(chǎn)生亂碼的根本原因。(JS和JSP都是這個(gè)道理)

    3、JSP,STRUTS等的中文亂碼解決方案
    其實(shí)解決的方法只有一個(gè):

    request.setCharacterEncoding(encoding);
    方法只有一種,但處理方式就多種多樣了,初學(xué)者會(huì)在JSP頁(yè)面上直接使用,而有經(jīng)驗(yàn)的程序員會(huì)使用過(guò)濾器。而現(xiàn)在所要說(shuō)的方法也是過(guò)濾器。這里以統(tǒng)一使用UTF-8作為編碼作為例子說(shuō)明。具體過(guò)程就不多說(shuō)了,網(wǎng)上有很多教程。偷懶一點(diǎn)的,到TOMCAT中復(fù)制就行了。在TOMCAT的目錄下的\webapps\jsp-examples\WEB-INF\classes\filters\找到SetCharacterEncodingFilter.java 這個(gè)類,放到你的程序中并配置好映射路徑。配置好后基本上你的亂碼問(wèn)題就解決了。但要映射路徑中需要注意的就是不能使用 '*'

    < filter-mapping >
    < filter-name > Set Character Encoding </ filter-name >
    < servlet-name > * </ servlet-name >
    </ filter-mapping >
    像上面這樣配置的話(可能也是網(wǎng)上大多教程的做法,想當(dāng)年也是害苦了我),可能你只有JSP的亂碼解決了,要解決STRUTS的亂碼需要映射 *.do 或者 servletActionName。然后在初始化參數(shù)中設(shè)置encoding的值就行了。

    < init-param >
    < param-name > encoding </ param-name >
    < param-value > UTF-8 </ param-value >
    </ init-param >
    當(dāng)然,最重要的是要記得根據(jù)前面所說(shuō)的方法,改變你所使用的編輯器保存文件的編碼要與使用的字符編碼一致。
    而在JSP內(nèi)容中,還是使用如網(wǎng)上教程所說(shuō)的那種技倆,在所有頁(yè)面的頁(yè)首加入:

    <% @ page language = "java" contentType = " text / html; charset = UTF - 8 "
    pageEncoding = "UTF - 8 " %>
    至此,相信JSP,ACTION都不太可能出現(xiàn)亂碼了。

    4、資源文件的亂碼解決方案
    資源文件誰(shuí)都知道是國(guó)際化支持不可或缺的一部分,如果資源文件都出現(xiàn)亂碼了那還了得?其實(shí)資源文件的亂碼是很好解決的,其原因也是因?yàn)槭褂昧薝TF-8做為JSP編碼后,沒(méi)有相應(yīng)地改變資源文件的文件編碼造成的,所以只要對(duì)資源文件保存的編碼進(jìn)行更正后,亂碼問(wèn)題也就解決了。當(dāng)然,你的中文要使用 native2ascii 命令進(jìn)行正確的轉(zhuǎn)換。

    5、調(diào)用JS時(shí),JS內(nèi)容亂碼的解決方案。
    其實(shí)JS的亂碼還是跟文件的編碼有關(guān)系的,如果JS中有中文的話,那JS文件保存的編碼就必須跟調(diào)用此JS的頁(yè)面編碼相同,否則,你的所有中文都要從JSP頁(yè)面?zhèn)鹘oJS才會(huì)顯示正常。可以看出對(duì)于調(diào)用JS出現(xiàn)的亂碼是最容易解決的(也是建立在前面的辛苦之下的)。

    6、AJAX提交數(shù)據(jù)亂碼,返回?cái)?shù)據(jù)亂碼的解決方案
    隨著AJAX的流行,亂碼問(wèn)題也開(kāi)始困擾著許多剛開(kāi)始使用它的程序員,幸好我之前對(duì)JSP亂碼有過(guò)一點(diǎn)研究,在遇到AJAX后,并沒(méi)有給我?guī)?lái)多大的困擾,在此將我的一些心得共享給大家。
    萬(wàn)變不離其宗,AJAX的亂碼問(wèn)題自然跟編碼有關(guān)了,其實(shí)很多人跟我一樣想到了對(duì)文件編碼進(jìn)行設(shè)置,并且在接數(shù)據(jù)時(shí)設(shè)置了requet的編碼,在返回的數(shù)據(jù)時(shí)設(shè)置了response的編碼一切都以為會(huì)很順利,可是這一切都是徒勞無(wú)功的,討厭的亂碼再一次出現(xiàn)在你眼前。在你試了N多種方法,包括JS自身的escape,unescape方法后,你發(fā)現(xiàn)亂碼仍然猖狂地出現(xiàn)在屏幕上。
    其實(shí)在試過(guò)這N多方法后,很多人都沒(méi)發(fā)現(xiàn),解決的方法其實(shí)很簡(jiǎn)單,而且其答案就在我們之前處理的JSP亂碼之中。讓我們先看一下AJAX的經(jīng)典請(qǐng)求代碼


    xmlhttp.open( "post", url, async );
    xmlhttp.setRequestHeader( "Content-Type", "text/html" );
    xmlhttp.send( params );
    通過(guò)前面的說(shuō)明,不知道你現(xiàn)在看出端倪了沒(méi)有。不知道是受了網(wǎng)上教程的影響還是其它方面影響,setRequestHeader并是萬(wàn)年不變的,也沒(méi)人想過(guò)去改它,而問(wèn)題就正好出在這個(gè)地方。回想一個(gè)JSP頁(yè)面內(nèi)容的編碼設(shè)置,其中有這么一節(jié): contentType="text/html; charset=UTF-8"
    現(xiàn)在知道問(wèn)題了吧,所以我們要把第二句代碼改為: xmlhttp.setRequestHeader( "Content-Type", "text/html;charset=UTF-8" );
    最后別忘了在返回?cái)?shù)據(jù)時(shí)也設(shè)置上: response.setContentType( "text/xml" );
    response.setCharacterEncoding( "UTF-8" );
    是不是很簡(jiǎn)單,一點(diǎn)都不麻煩呢?
    如果要問(wèn)為什么的話,其實(shí)我們可以把xmlhttp看成是一個(gè)臨時(shí)頁(yè)面,它由瀏覽器動(dòng)態(tài)生成,主要作用是在后臺(tái)獲得請(qǐng)求的數(shù)據(jù)(可以看成是一個(gè)高級(jí)的iframe)。所以對(duì)于普通頁(yè)面設(shè)置的編碼,對(duì)它也要同樣設(shè)置。而在servlet中返回?cái)?shù)據(jù)為什么要設(shè)置contentType和encoding其道理也是一樣的。眾所周知,jsp的最后形態(tài)就是servlet,而jsp頁(yè)首設(shè)置的那個(gè)內(nèi)容其實(shí)也就是讓生成的servlet中生成這么兩句話:
    response.setContentType( "text/html" );
    response.setCharacterEncoding( "UTF-8" );
    而pageEncoding則是跟jvm說(shuō)明了這個(gè)頁(yè)面的內(nèi)容要使用什么編碼保存(這跟之后生成的CLASS有關(guān)系)。所以在servlet設(shè)置response的編碼也是理所當(dāng)然的了。

    J2ee中文問(wèn)題的解決

     

    第一,文件的的編碼方式其實(shí)就包括兩方面:存和取,存文件必須以一種編碼存;讀文件也必須以一種編碼讀。如果存取按照相同的編碼方式,則不會(huì)有問(wèn)題,關(guān)鍵就是很多時(shí)候存取的方式不一致,產(chǎn)生亂碼。,如不特別設(shè)置取系統(tǒng)默認(rèn)的編碼,中文windows為GBK編碼。

    從.java->.class過(guò)程是,先編寫(xiě).java文件并按莫種編碼方式保存,然后用javac方法編譯此文件,注意如.java沒(méi)按系統(tǒng)默認(rèn)編碼保存則要帶encoding參數(shù)指明實(shí)際編碼,否則出錯(cuò),生成的.class文件存為系統(tǒng)默認(rèn)編碼。

    從.jsp->.java->.class,先存為某種編碼的.jsp文件,然后tomcat根據(jù)pageEncoding讀取并轉(zhuǎn)化為servlet存為系統(tǒng)默認(rèn)編碼,然后同上面.java->.class過(guò)程。

    第二,IDE的encoding為對(duì)系統(tǒng)下文件打開(kāi)的解碼方式或保存的編碼方式。特例:如果.jsp文件有<%@ page language="java" pageEncoding="UTF-8"%>,則eclipse會(huì)自動(dòng)存為UTF-8方式,不管eclipse的encoding是什么,這也是 eclipse的聰明之處。

    第三,
    pageEncoding="UTF-8"表示此文件的編碼方式,必須與此文件存儲(chǔ)方式一致(所以eclipse會(huì)首選根據(jù)它來(lái)存文件),tomcat根據(jù)這個(gè)來(lái)讀此.jsp文件并編譯為servlet(至于編譯成的.java和.class文件應(yīng)該為tomcat服務(wù)器默認(rèn)編碼)。
    contentType="text/html;charset=UTF-8"表示當(dāng)服務(wù)器給瀏覽器傳頁(yè)面文件時(shí)編碼方式為UTF-8,形式為HTML。例如:
    <%@ page language="java" pageEncoding="UTF-8"%>
    <%@ page contentType="text/html;charset=GBK"%>
    <html>
     <head>
      <title>test</title>
     </head>
     <body>
      我是個(gè)好人
     </body>
    </html>

    表示本jsp文件存為UTF-8字符集,當(dāng)瀏覽器打開(kāi)此頁(yè)面后,查看原碼就會(huì)發(fā)現(xiàn)源碼為GBK字符集。

    第四,
    request.setCharacterEncoding("UTF-8")是把提交內(nèi)容的字符集設(shè)為UTF-8
    response.setCharacterEncoding("UTF-8")可以把頁(yè)面中的<%@ page contentType="text/html;charset=iso8859-1"%>換為charset=UTF-8,是給告訴瀏覽器我這個(gè)文件的編碼方式。

    第五,表單提交:無(wú)論何種表單提交都可以在后臺(tái)的java文件中通過(guò)String des = new String(s.getBytes("iso8859-1"),"UTF-8");來(lái)轉(zhuǎn)換成你想要的UTF-8編碼方式。但如果每處都加詞句太麻煩,故分post和get兩種方式區(qū)分提交(tomcat5以后分開(kāi)處理,之前處理方式一樣,即都可以用 request.setCharacterEncoding("UTF-8")方法處理,不過(guò)tomcat5以后get提交方法用此語(yǔ)句無(wú)效)。
    1,post提交的數(shù)據(jù):
    程序加上org.springframework.web.filter.CharacterEncodingFilter過(guò)濾器.
    <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
    <param-name>encoding</param-name>
    <param-value>UTF8</param-value>
    </init-param>
    <init-param>
    <param-name>forceEncoding</param-name>
    <param-value>true</param-value>
    </init-param>
    </filter>

    <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>*.html</url-pattern>
    </filter-mapping>
    <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>*.jsp</url-pattern>
    </filter-mapping>

    因?yàn)橐?guī)范要求瀏覽器提交數(shù)據(jù)都要用utf8編碼,所以這里設(shè)置編碼方式為UTF8.

    特別注意:
    a,這個(gè)過(guò)濾器只是簡(jiǎn)單的調(diào)用:request.setCharacterEncoding(this.encoding);
    在這個(gè)語(yǔ)句之前不能調(diào)用任何的request.getParameter()方法,否則會(huì)設(shè)置tomcat的缺省字符集為"ISO-8859-1",并且使 setCharacterEncoding的調(diào)用失效.所以在這個(gè)過(guò)濾器之前的過(guò)濾器中不能有對(duì)getParameter這類方法的調(diào)用,比較安全的做法就是把這個(gè)過(guò)濾器盡量靠前放.
    b,在server.xml中不能加上<Valve className="org.apache.catalina.valves.RequestDumperValve"/>
    這個(gè)value也設(shè)置tomcat的缺省字符集為"ISO-8859-1",使setCharacterEncoding的調(diào)用失效.可能其他的value也有這個(gè)問(wèn)題,我沒(méi)有測(cè)試過(guò).
    如果要觀察http請(qǐng)求參數(shù),可以考慮用過(guò)濾器或者其他工具,例如ethereal(http://www.ethereal.com/)

    2,get提交的數(shù)據(jù):
    兩種情況:
    a,如果從地址欄直接輸入漢字,則一般編碼為"GBK",需要用
    new String(request.getParameter("something").getBytes("ISO-8859-1"),"GBK")
    取出
    b,如果是頁(yè)面超連接連接中帶的漢字,則編碼根據(jù)頁(yè)面編碼的不同而不同,如果頁(yè)面的
    content="text/html; charset=utf-8",則在tomcat/conf/server.xml中的配置文件中:
    <!-- Define a non-SSL Coyote HTTP/1.1 Connector on port 8080 -->
    <Connector port="8080"
    maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
    enableLookups="false" redirectPort="8443" acceptCount="100"
    debug="0" connectionTimeout="20000" useBodyEncodingForURI="true"
    disableUploadTimeout="true" />

    加上:useBodyEncodingForURI="true"即可正常使用getParameter取出正確內(nèi)容.
    如果content="text/html; charset=GBK",需用
    new String(request.getParameter("something").getBytes("ISO-8859-1"),"GBK")
    取出,其他情況類似.

    總結(jié):
    1,所有頁(yè)面使用utf8編碼,
    2,服務(wù)器加上過(guò)濾器,
    3,server.xml中不要使用
    <Valve className="org.apache.catalina.valves.RequestDumperValve"/>
    4,server.xml文件加上useBodyEncodingForURI="true"
    這樣應(yīng)該可以搞定大多數(shù)前臺(tái)的中文問(wèn)題.至于地址欄輸入中文,不支持也罷,一般的程序很少要求
    從這里輸入.

    第六,連接數(shù)據(jù)庫(kù)
     

    1、mysql配置文件:
    修改mysql在windows\my.ini里default-character-set=utf-8

    2、mysql里數(shù)據(jù)庫(kù)和表也都設(shè)為utf8_unicode_ci

    3、數(shù)據(jù)庫(kù)連結(jié):jdbc:mysql://localhost/mydb?useUnicode=true&characterEncoding=utf-8
    注意,關(guān)鍵就在于此:此句中間是'&'不是'&amp;'這是因?yàn)閿?shù)據(jù)庫(kù)連結(jié)時(shí),在.jsp和.java文件中應(yīng)該用&號(hào),而XML文件中需要用&amp

     

    JSP/Servlet的編碼原理

    關(guān)鍵字: JSP,Servlet編碼

    首先,說(shuō)說(shuō)JSP/Servlet中的幾個(gè)編碼的作用

    在JSP/Servlet中主要有以下幾種設(shè)置編碼的方式:

    1. pageEncoding ="UTF-8"
    2. contentType = "text/html;charset=UTF-8"
    3. request.setCharacterEncoding("UTF-8")
    4. response.setCharacterEncoding("UTF-8")

    其中前兩個(gè)只能用于JSP中,而后兩個(gè)可以用于JSP和Servlet 中。

    1、pageEncoding="UTF-8"的作用是設(shè)置JSP編譯成Servlet時(shí)使用的編碼

    眾所周知,JSP在服務(wù)器上是要先被編譯成Servlet的。pageEncoding="UTF-8"的作用就是告訴JSP編譯器在將 JSP文件編譯成Servlet時(shí)使用的編碼。通常,在JSP內(nèi)部定義的字符串(直接在JSP中定義,而不是從瀏覽器提交的數(shù)據(jù))出現(xiàn)亂碼時(shí),很多都是由于該參數(shù)設(shè)置錯(cuò)誤引起的。例如,你的JSP文件是以GBK為編碼保存的,而在JSP中卻指定pageEncoding="UTF-8",就會(huì)引起JSP內(nèi)部定義的字符串為亂碼。

    另外,該參數(shù)還有一個(gè)功能,就是在JSP中不指定contentType參數(shù),也不使用response.setCharacterEncoding方法時(shí),指定對(duì)服務(wù)器響應(yīng)進(jìn)行重新編碼的編碼。

    2、contentType="text/html;charset=UTF-8"的作用是指定對(duì)服務(wù)器響應(yīng)進(jìn)行重新編碼的編碼

    在不使用response.setCharacterEncoding方法時(shí),用該參數(shù)指定對(duì)服務(wù)器響應(yīng)進(jìn)行重新編碼的編碼。

    3、request.setCharacterEncoding("UTF-8")的作用是設(shè)置對(duì)客戶端請(qǐng)求進(jìn)行重新編碼的編碼。

    該方法用來(lái)指定對(duì)瀏覽器發(fā)送來(lái)的數(shù)據(jù)進(jìn)行重新編碼(或者稱為解碼)時(shí),使用的編碼。

    4、response.setCharacterEncoding("UTF-8")的作用是指定對(duì)服務(wù)器響應(yīng)進(jìn)行重新編碼的編碼。

    服務(wù)器在將數(shù)據(jù)發(fā)送到瀏覽器前,對(duì)數(shù)據(jù)進(jìn)行重新編碼時(shí),使用的就是該編碼。

    其次,要說(shuō)一說(shuō)瀏覽器是怎么樣對(duì)接收和發(fā)送的數(shù)據(jù)進(jìn)行編碼的

    response.setCharacterEncoding("UTF-8")的作用是指定對(duì)服務(wù)器響應(yīng)進(jìn)行重新編碼的編碼。同時(shí),瀏覽器也是根據(jù)這個(gè)參數(shù)來(lái)對(duì)其接收到的數(shù)據(jù)進(jìn)行重新編碼(或者稱為解碼)。所以在無(wú)論你在JSP中設(shè)置response.setCharacterEncoding("UTF-8")或者response.setCharacterEncoding ("GBK"),瀏覽器均能正確顯示中文(前提是你發(fā)送到瀏覽器的數(shù)據(jù)編碼是正確的,比如正確設(shè)置了pageEncoding參數(shù)等)。讀者可以做個(gè)實(shí)驗(yàn),在JSP中設(shè)置response.setCharacterEncoding("UTF-8"),在IE中顯示該頁(yè)面時(shí),在IE的菜單中選擇"查看 (V)"à"編碼(D)"中可以查看到是" Unicode(UTF-8)",而在在JSP中設(shè)置response.setCharacterEncoding("GBK"),在IE中顯示該頁(yè)面時(shí),在IE的菜單中選擇"查看(V)"à"編碼(D)"中可以查看到是"簡(jiǎn)體中文(GB2312)"。

    瀏覽器在發(fā)送數(shù)據(jù)時(shí),對(duì)URL和參數(shù)會(huì)進(jìn)行URL編碼,對(duì)參數(shù)中的中文,瀏覽器也是使response.setCharacterEncoding參數(shù)來(lái)進(jìn)行URL編碼的。以百度和GOOGLE為例,如果你在百度中搜索"漢字",百度會(huì)將其編碼為"%BA%BA%D7%D6"。而在GOOGLE中搜索"漢字",GOOGLE會(huì)將其編碼為"%E6%B1%89%E5%AD%97",這是因?yàn)榘俣鹊膔esponse.setCharacterEncoding參數(shù)為GBK,而GOOGLE的的response.setCharacterEncoding參數(shù)為UTF-8。

    瀏覽器在接收服務(wù)器數(shù)據(jù)和發(fā)送數(shù)據(jù)到服務(wù)器時(shí)所使用的編碼是相同的,默認(rèn)情況下均為JSP頁(yè)面的 response.setCharacterEncoding參數(shù)(或者contentType和pageEncoding參數(shù)),我們稱其為瀏覽器編碼。當(dāng)然,在IE中可以修改瀏覽器編碼(在IE的菜單中選擇"查看(V)"à"編碼(D)"中修改),但通常情況下,修改該參數(shù)會(huì)使原本正確的頁(yè)面中出現(xiàn)亂碼。一個(gè)有趣的例子是,在IE中瀏覽GOOGLE的主頁(yè)時(shí),將瀏覽器編碼修改為"簡(jiǎn)體中文(GB2312)",此時(shí),頁(yè)面上的中文會(huì)變成亂碼,不理它,在文本框中輸入"漢字",提交,GOOGLE會(huì)將其編碼為"%BA%BA%D7%D6",可見(jiàn),瀏覽器在對(duì)中文進(jìn)行URL編碼時(shí),使用的就是瀏覽器編碼。

    弄清了瀏覽器是在接收和發(fā)送數(shù)據(jù)時(shí),是如何對(duì)數(shù)據(jù)進(jìn)行編碼的了,我們?cè)賮?lái)看看服務(wù)器是在接收和發(fā)送數(shù)據(jù)時(shí),是如何對(duì)數(shù)據(jù)進(jìn)行編碼的。

    對(duì)于發(fā)送數(shù)據(jù),服務(wù)器按照response.setCharacterEncoding—>contentType—>pageEncoding的優(yōu)先順序,對(duì)要發(fā)送的數(shù)據(jù)進(jìn)行編碼。

    對(duì)于接收數(shù)據(jù),要分三種情況。一種是瀏覽器直接用URL提交的數(shù)據(jù),另外兩種是用表單的GET和POST方式提交的數(shù)據(jù)。

    因?yàn)楦鞣NWEB服務(wù)器對(duì)這三種方式的處理也不相同,所以我們以Tomcat5.0為例。

    無(wú)論使用那種方式提交,如果參數(shù)中包含中文,瀏覽器都會(huì)使用當(dāng)前瀏覽器編碼對(duì)其進(jìn)行URL編碼。

    對(duì)于表單中POST方式提交的數(shù)據(jù),只要在接收數(shù)據(jù)的JSP中正確request.setCharacterEncoding參數(shù),即將對(duì)客戶端請(qǐng)求進(jìn)行重新編碼的編碼設(shè)置成瀏覽器編碼,就可以保證得到的參數(shù)編碼正確。有寫(xiě)讀者可能會(huì)問(wèn),那如何得到瀏覽器編碼呢?上面我們提過(guò)了,在默認(rèn)請(qǐng)情況下,瀏覽器編碼就是你在響應(yīng)該請(qǐng)求的JSP頁(yè)面中response.setCharacterEncoding設(shè)置的值。所以對(duì)于POST表單提交的數(shù)據(jù),在獲得數(shù)據(jù)的JSP頁(yè)面中request.setCharacterEncoding要和生成提交該表單的JSP頁(yè)面的 response.setCharacterEncoding設(shè)置成相同的值。

    對(duì)于URL提交的數(shù)據(jù)和表單中GET方式提交的數(shù)據(jù),在接收數(shù)據(jù)的JSP中設(shè)置 request.setCharacterEncoding參數(shù)是不行的,因?yàn)樵赥omcat5.0中,默認(rèn)情況下使用ISO-8859-1對(duì)URL提交的數(shù)據(jù)和表單中GET方式提交的數(shù)據(jù)進(jìn)行重新編碼(解碼),而不使用該參數(shù)對(duì)URL提交的數(shù)據(jù)和表單中GET方式提交的數(shù)據(jù)進(jìn)行重新編碼(解碼)。要解決該問(wèn)題,應(yīng)該在Tomcat的配置文件的Connector標(biāo)簽中設(shè)置useBodyEncodingForURI或者URIEncoding屬性,其中 useBodyEncodingForURI參數(shù)表示是否用request.setCharacterEncoding參數(shù)對(duì)URL提交的數(shù)據(jù)和表單中 GET方式提交的數(shù)據(jù)進(jìn)行重新編碼,在默認(rèn)情況下,該參數(shù)為false(Tomcat4.0中該參數(shù)默認(rèn)為true);URIEncoding參數(shù)指定對(duì)所有GET方式請(qǐng)求(包括URL提交的數(shù)據(jù)和表單中GET方式提交的數(shù)據(jù))進(jìn)行統(tǒng)一的重新編碼(解碼)的編碼。URIEncoding和 useBodyEncodingForURI區(qū)別是,URIEncoding是對(duì)所有GET方式的請(qǐng)求的數(shù)據(jù)進(jìn)行統(tǒng)一的重新編碼(解碼),而 useBodyEncodingForURI則是根據(jù)響應(yīng)該請(qǐng)求的頁(yè)面的request.setCharacterEncoding參數(shù)對(duì)數(shù)據(jù)進(jìn)行的重新編碼(解碼),不同的頁(yè)面可以有不同的重新編碼(解碼)的編碼。所以對(duì)于URL提交的數(shù)據(jù)和表單中GET方式提交的數(shù)據(jù),可以修改URIEncoding 參數(shù)為瀏覽器編碼或者修改useBodyEncodingForURI為true,并且在獲得數(shù)據(jù)的JSP頁(yè)面中 request.setCharacterEncoding參數(shù)設(shè)置成瀏覽器編碼。

    下面總結(jié)下,以Tomcat5.0為WEB服務(wù)器時(shí),如何防止中文亂碼

    1. 對(duì)于同一個(gè)應(yīng)用,最好統(tǒng)一編碼,推薦為UTF-8,當(dāng)然GBK也可以。
    2. 正確設(shè)置JSP的pageEncoding參數(shù)
    3. 在所有的JSP/Servlet中設(shè)置contentType="text/html;charset=UTF-8"或response.setCharacterEncoding("UTF-8"),從而間接實(shí)現(xiàn)對(duì)瀏覽器編碼的設(shè)置。
    4. 對(duì)于請(qǐng)求,可以使用過(guò)濾器或者在每個(gè)JSP/Servlet中設(shè)置request.setCharacterEncoding ("UTF-8")。同時(shí),要修改Tomcat的默認(rèn)配置,推薦將useBodyEncodingForURI參數(shù)設(shè)置為true,也可以將 URIEncoding參數(shù)設(shè)置為UTF-8(有可能影響其他應(yīng)用,所以不推薦.)。
    posted @ 2008-08-08 11:18 二胡 閱讀(451) | 評(píng)論 (0)編輯 收藏

    僅列出標(biāo)題
    共165頁(yè): First 上一頁(yè) 126 127 128 129 130 131 132 133 134 下一頁(yè) Last 
    主站蜘蛛池模板: 91久久亚洲国产成人精品性色 | 国产亚洲视频在线播放大全| 老色鬼久久亚洲AV综合| 免费一级毛片在线播放不收费 | 亚洲最大成人网色香蕉| 亚洲AV无码专区在线播放中文| 亚洲成A∨人片天堂网无码| 成人毛片免费播放| 67194熟妇在线永久免费观看 | 久久久久久亚洲精品中文字幕| 亚洲Av无码乱码在线znlu| 拍拍拍又黄又爽无挡视频免费| 无码国产精品一区二区免费16| 你懂得的在线观看免费视频| 一区二区免费在线观看| 亚洲AV日韩AV一区二区三曲| 2020天堂在线亚洲精品专区| 亚洲欧洲尹人香蕉综合| 日韩免费无码视频一区二区三区| 51午夜精品免费视频| 一级女性全黄生活片免费看| 校园亚洲春色另类小说合集 | 亚洲成A人片在线观看中文| 日本一线a视频免费观看| 性感美女视频在线观看免费精品| 91频在线观看免费大全| 1000部拍拍拍18勿入免费视频软件 | 无码国产精品一区二区免费16 | 久久国产亚洲高清观看| 久久精品a亚洲国产v高清不卡| 亚洲成人激情在线| 4444亚洲国产成人精品| 亚洲欧洲高清有无| 久久精品国产亚洲精品2020| 亚洲国产品综合人成综合网站| 亚洲导航深夜福利| 亚洲无人区码一二三码区别图片| 亚洲欧洲无码一区二区三区| 国产精品亚洲综合天堂夜夜| 三级片免费观看久久| 成人爽a毛片免费|