亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

解決字符集亂碼問題完全攻略

系統(tǒng) 2799 0

????? 最近又碰到了中文亂碼問題,這里我沒有把數(shù)據(jù)庫牽扯進來,先說下我的環(huán)境,servlet容器使用Tomcat6.0,瀏覽器FireFox3.0、IE6,涉及字符編碼設(shè)置的地方我的思路就是編碼的地方都統(tǒng)一使用UTF-8,具體配置如下:

1.所有頁面的charset設(shè)置為UTF-8。

2.Tomcat的URIEncoding默認是ISO-8859-1,而我設(shè)置為UTF-8,主要是想解決中文命名的文件以及請求以get方式提交有可能出現(xiàn)的亂碼問題。

3.添加過濾器,調(diào)用request.setCharacterEncoding("utf-8")方法將request的字符集設(shè)定為utf-8,解決請求以post方式提交的亂碼問題。

其實這樣的設(shè)置貌似是不會再出現(xiàn)亂碼問題了,不過,問題依舊來了 ,如果我在瀏覽器的地址欄中輸入中文參數(shù)提交,返回的頁面卻出現(xiàn)了亂碼。真搞不明白到底是哪里出了問題!說起來對中文亂碼的問題一直是一支半解,出現(xiàn)亂碼了,網(wǎng)上搜羅了一大堆資料,按照網(wǎng)上的配置,問題到是解決了,不過原理卻搞的很模糊,一個請求發(fā)送到服務器,服務器業(yè)務邏輯處理后返回一個頁面,這中間涉及的字符集轉(zhuǎn)換,編碼,解碼過程一概不清楚。這次,折騰了半天,總算是更進一步了解了字符編碼問題,這里做個總結(jié)。

先看我的總結(jié),有不對的地方歡迎批評。

首先我們看下,一個請求響應的流程

?

瀏覽器 IE/FireFox ----------->Servlet容器------------------------>顯示頁面

?????? 編碼?????????????????????????? 使用容器的URIEncoding轉(zhuǎn)碼 ???????????? 解碼

我把用戶發(fā)送請求方式不同引起的中文問題劃分了四種類型:

1、表單的get提交

2、表單的post提交

3、頁面鏈接傳遞中文參數(shù)

4、地址欄中參數(shù)直接輸入中文提交

?

1.首先我們看表單get方式提交

????? 瀏覽器根據(jù)頁面的charset編碼方式對頁面進行編碼,然后提交至服務器,首先進入對應的字符編碼過濾器(如果有的話),不過Tomcat6.0對于get提交方式采用的是server.xml文件中的URIEncoding編碼方式,而并不會采用過濾器中設(shè)置的編碼,那么根據(jù)我的環(huán)境設(shè)置,jsp頁面都使用UTF-8的編碼,Servlet容器的URIEncoding也設(shè)置為UTF-8,則servlet不用進行轉(zhuǎn)碼即可正確解碼,獲得正常的中文字符串。那么,響應頁面的中文因為頁面的統(tǒng)一編碼(UTF-8)自然也會正常顯示。當然,如果我們Tomcat的URIEncoding設(shè)置為其他非UTF-8的編碼方式時,頁面的內(nèi)容進入Tomcat解析時,因為Tomcat和頁面的編碼不統(tǒng)一,就需要轉(zhuǎn)碼。例如,如果我們采用Tomcat默認的ISO-8859-1,那么當我們使用request.getParameter("your Variable ")獲取表單參數(shù)值時其實Servlet就進行了轉(zhuǎn)碼,它會以容器編碼方式進行解碼,這個過程如下:

UTF-8(編碼)-->ISO-58859-1(解碼)

這個過程也相當于我們使用如下的語句

Java代碼 復制代碼
  1. new ?String(變量值.getBytes( "UTF-8" ), "ISO-8859-1" );??
    new String(變量值.getBytes("UTF-8"),"ISO-8859-1");
  

根據(jù)API的解釋,先將變量值以UTF-8字符集編碼轉(zhuǎn)換為字節(jié)序列,再以ISO-8859-1字符集解碼字節(jié)數(shù)組,構(gòu)造出新的字符串對象。

等價于以下方式:

Java代碼 復制代碼
  1. String?code?=? "編碼" ; ??
  2. code?=?URLEncoder.encode(code, "UTF-8" ); ??
  3. code?=?URLDecoder.decode(code, "ISO-8858-1" );??
    String code = "編碼";
code = URLEncoder.encode(code,"UTF-8");
code = URLDecoder.decode(code,"ISO-8858-1");

  

?

例如表單的username屬性以字符串"編輯"提交,那么進入容器后,F(xiàn)ormBean中的這個變量會亂碼,request.getParameter(username)一樣的效果,s1就是request返回的結(jié)果,下面是內(nèi)存快照。

不過即使這樣,我們依然可以使用不恰當?shù)姆椒@示正常的中文,即逆向轉(zhuǎn)碼,例如上面的亂碼,我們可以通過ISO8859-1-->UTF-8這種方式還原我們提交時的中文。以下是GBK,UTF-8,ISO-8859-1三者之間互相轉(zhuǎn)換的內(nèi)存快照:

?我們可以看到,偶數(shù)漢字可以在UTF-8,GBK兩者中互相轉(zhuǎn)換,而奇數(shù)個漢字則不能。綜上看來,貌似Tomcat的URIEncoding設(shè)置為UTF-8是最好的解決辦法,不過這樣的設(shè)置依然無法解決上面我所說的第三、第四種情況。大家繼續(xù)向下看。(這里有一點我不確定,就是頁面提交至Servlet容器時,是以頁面的charset方式編碼后直接進入容器,還是以charset轉(zhuǎn)碼為ISO-8859-1方式進入,大家有什么見解?)
2.表單的post提交

對于這種方式的請求,request.setCharacterEncoding("一般來自于web.xml中過濾器設(shè)置的參數(shù)")方法進行編碼設(shè)置將會產(chǎn)生作用,struts的表單提交方式默認為post方式,那么按照上面我的環(huán)境設(shè)置,頁面,容器,都采用UTF-8編碼方式,就不會產(chǎn)生中文亂碼問題。
3.頁面鏈接中傳遞中文參數(shù)

我虛擬一個這樣的場景,請求頁面中有如下代碼

Html代碼 復制代碼
  1. < % ??
  2. String? username ?=? "編輯" ; ??
  3. % > ??
  4. < a ? href = "hello.do?username=<%=username%>" > 頁面中鏈接傳遞中文 </ a > ??
    <%
String username = "編輯";
%>
<a href="hello.do?username=<%=username%>">頁面中鏈接傳遞中文</a>
  

對于這種方式,我們需要先將參數(shù)使用統(tǒng)一的編碼方式編碼,將編碼后的字符放入鏈接,這里我對參數(shù)以UTF-8方式編碼,如下

Java代碼 復制代碼
  1. <% ??
  2. String?username?=?java.net.URLEncoder.encode( "編輯" , "UTF-8" ); ??
  3. %>??
    <%
String username = java.net.URLEncoder.encode("編輯","UTF-8");
%>
  

那么這樣我們也不會產(chǎn)生中文亂碼問題

4.地址欄中參數(shù)直接輸入中文提交

例如瀏覽器地址欄中輸入"http://localhost:8080/helloapp.do?username=編輯"提交,對于這種方式,瀏覽器不會采用頁面的charset方式對URL中的中文進行編碼后提交至服務器(IE,FireFox都一樣),而是采用系統(tǒng)的GBK轉(zhuǎn)碼為ISO-8859-1之后提交至Servlet容器,那么,如果對于前三種方式我們所做的設(shè)置,在這里就有問題了,因為進入容器時中文進行了GBK至ISO-8859-1的轉(zhuǎn)碼,而之前我們的Servlet容器URIEncoding設(shè)置為UTF-8,當我們使用request.getParameter("username")時,相當于又進行了這樣的流程GBK-->ISO-8859-1-->UTF-8,按照以上我們使用的測試中文,“編輯”,使用request.getParameter("username")則會得到這樣的結(jié)果??,下圖是進行轉(zhuǎn)碼的內(nèi)存快照:


我們可以看到

“編輯”經(jīng)過從GBK-->ISO-8859-1-->UTF-8的過程后得到的就是??這樣的結(jié)果,這里我們還會想到那進行2次逆向轉(zhuǎn)碼看看,不過可惜的是,結(jié)果為“錕潔輯”。對于這種情況,我們的解決辦法就是,Tomcat的URIEncoding采用默認的ISO-8859-1字符集,那么我們可以在程序中通過ISO-8859-1-->GBK這樣不恰當?shù)哪嫦蜣D(zhuǎn)碼方式得到正常的中文“編輯”,但這樣的結(jié)果是,我們get請求方式的中文處理解決辦法就需要改變。如,在我的環(huán)境下就需要進行ISO-8859-1-->UTF-8的轉(zhuǎn)碼,挺不爽。

?

綜上,對于亂碼問題,前三種方式是一般用戶的請求方式,第四種屬于非正常途徑的請求方式,對于這種方式產(chǎn)生的問題我認為無法很好的解決,也不需要解決。我看到j(luò)avaeye對于這樣的情況就沒有處理,不知道大家在自己的項目中是如何處理的?我的實驗是,IE6的設(shè)置會影響應用路徑的編碼方式,例如地址欄中請求一個中文JSP頁面,如:http://localhost:8080/helloapp/編輯.jsp,IE默認是勾選"以UTF-8發(fā)送URL"項的,那么按照我上面總結(jié)的處理方式,這個請求可以正常顯示頁面,如圖:

如果取消IE的這個選項,那么瀏覽器會以GBK編碼應用路徑的中文,得到的結(jié)果如圖:

按照我上面的設(shè)置,這里如果將Tomcat的URIEncoding設(shè)置為GBK,則也可以正常顯示頁面。對于FireFox3.0,則是以UTF-8編碼。

最后,回到我的題目,向大家討教下,IE6的“以UTF-8發(fā)送URL”選項設(shè)置對請求頁面字符編碼有影響嗎?歡迎討論!

?

我的測試代碼共享給大家:),使用的是struts1.2,struts的jar包,大家可以去apache下載。

?

這里推薦個鏈接,有興趣的可以深入了解更多字符集、編碼的問題。

http://hideto.iteye.com/blog/97803

解決字符集亂碼問題完全攻略


更多文章、技術(shù)交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 九九亚洲精品 | 天天干人人干 | 天天做天天爱天天操 | 老头与老头同性tube可播放 | 国产精品99久久 | 亚洲高清视频一区 | 四虎永久免费884hutv | 一级毛片免费视频日本 | 狠狠操在线观看 | 欧美日韩综合高清一区二区 | 91在线看片一区国产 | 成人免费黄色 | 中文字幕在线精品视频入口一区 | 五月综合激情视频在线观看 | 9久9久热精品视频在线观看 | 中文字幕久久综合伊人 | 精品一区二区三区四区乱码90 | 天天搞天天搞 | 日韩综合一区 | 中文字幕欧美在线观看 | 国产精品欧美亚洲区 | 亚洲黄色a级片 | 久久国内精品自在自线400部o | 精品夜夜春夜夜爽久久 | 99精品视频在线观看 | 精品亚洲性xxx久久久 | 51国产午夜精品免费视频 | 亚洲精品国产乱码在线播 | 亚洲一区三区 | 精品综合久久久久97 | 福利视频专区 | 俄罗斯色视频 | 青青青视频精品中文字幕 | 97综合 | 欧美色视频日本片免费高清 | 亚洲精品一二三区 | 99热这 | 69成人网 | 久久99国产精品二区不卡 | 国产精品女仆装在线播放 | 热久久精品 |