解析訪問JSP一系列的編碼解碼過程-詳細

來源:互聯網
上載者:User
解析訪問JSP一系列的編碼解碼過程-詳細

出自:http://japi.javaeye.com/blog/288779


亂碼是個讓人頭痛的問題...

頁面的亂碼,servlet中的亂碼,資料庫的亂碼....

一個煩字了得..

解決的方法也很早就出來...不多講...

先看看兩個網址:

http://www.google.cn/search?client=aff-cs-worldbrowser&forid=1&ie=utf-8&oe=UTF-8&hl=zh-CN&q=開源

http://www.javaeye.com/search?type=all&query=分頁

點擊看看什麼效果..選中URL,再斷行符號看看...

--------------------------------------------------------

說說從URL到servlet再到頁面的一系列編碼解碼過程..

首Crowdsourced Security Testing道在JAVA中的字元都是使用unicode

其次,我們假定在頁面中使用了utf-8編碼,當然你還可以使用gb2312之類的...但強烈建議你使用utf-8

1.輸入URL...

    此時,servlet引擎就做些事..

    把URL進行編碼,按照ISO8859-1字元集編碼進行轉換成UNICODE,再封裝到ServletRequest對象中.

    當我們使用表單的時候,post,get方式,會以頁面的字元編碼對錶單中的內容進行,編碼.這個過程有點像URLEncoder.encode()方法的效果...

2.得到URL中的參數..

    這是我們常做的,一個方法而已嘛..request.getParameter("paramName")

   這個方法的背後還有一些解碼工作..

   亂碼的原因有時就在此..

   getParamter方法,對URL進行解碼,在servlet規範中沒有明確規定解碼所採用的字元集編碼,它由各個servlet引擎廠商自行決定...tomcat中預設採用ISO8859-1字元集進行URL解碼.

   對於post方式:可以使用request.setCharacterEncoding(),方法指定別的解碼方式.

   對於get方式:

   可以使用原始的方法new String(param.getBytes("iso8859-1"),"utf-8")

這條語句在這兒的作用:

   把getParameter方法解碼成的錯誤unicode還原成正確的編碼.

怎麼講呢?這兒解釋有點麻煩..

在頁面中提交表單的時候,表單內容使用頁面字元碼utf-8編碼,而getParameter預設的方法是以iso8859-1解碼的,所以如果你不處理下,就會是亂碼了...

ISO8859-1與unicode之間的轉換是無損的..

  我們使用getBytes("iso8859-1")還原成正確的字元數組,再以utf-8編碼,就得到正確的結果了..

   這個過程是這樣的:

    (以utf-8編碼)           getParameter以(ios8859-1)解碼

URL--------------->字元數組------------------------------>UNICODE(錯誤)

   

   使用getBytes("iso8859-1")還原         new String(bytes,"utf-8")

UNICODE------------------------>字元數組--------------->UNICODE(正確)-            

  也可以修改server.xml
Java代碼

  1. <Connector port="8080" protocol="HTTP/1.1"   
  2.               connectionTimeout="20000"   
  3.               redirectPort="8443" <span style="color: red;">URIEncoding="utf-8</span>"/>  
 <Connector port="8080" protocol="HTTP/1.1"                connectionTimeout="20000"                redirectPort="8443" URIEncoding="utf-8"/>

讓url解碼時使用utf-8.

   

   記得上面讓做實驗嗎...選中URL,斷行符號.此時,URL中的中文字元是以本地符編碼的.就是GB2312編碼..

   像javaeye的.URL中的是GB2312,而在幕後處理的時候以使用的utf-8,所以就出現了亂碼..google的那個,
參數中有個ie,那可能就是瀏覽器的編碼,如果改成gb2312就不會出現亂碼...在這個方面.google比baidu做得優秀..頁面的編碼也會根
據這個參數來確定,..而baidu只是對gb2312處理了..所以從這點看,baidu還是沒有走向國際化..你可以再做實驗驗證下..

   直接在輸入URL,過程也一樣

   先對URL編碼,以ISO8859-1編碼,getParameter解碼..GB2312---->UNICODE

 

3,頁面得到字元.

   在servlet中,都是unicode的編碼,會以request.setCharacter()編碼成字元數組.

在頁面中顯示時,再以contentType屬性解碼一下..所有這兩處得一致.!

----------------------

以上就是其中的一些過程,還有一些細節...

比如在servlet中沒有使用setCharacterEncoding方法,也沒有使用相應的filter處理,

那麼如果有URL的參數的時候,顯示得使用URLEncoder.encode()編碼下..在頁面上的URL中才會正確顯示..

   對於編碼和解碼,都是對稱的...底層都是使用位元組數組來傳遞,我們只要知道了這個位元組數組是怎麼得到的就知道怎麼去處理,也知道亂碼原因在哪一步...

   
比如輸入URL,URL中的是GB2312,先是URL編碼,GB2312以ISO8859-1---->位元組數組..getParameter又
以ISO8859-1對位元組數組解碼,此時,你寫上new
String(p.getBytes("iso8859-1"),"utf-8")就是亂碼...

寫p.getBytes("iso8859-1"),"gb2312"就是正確的..

   在搜尋分頁的時候,下一頁帶的中文參數,一般都會在頁面上顯示得對它進行URLEncoder.encode,如果沒有,就得在servlet中進行重新解碼..也就是getBytes一下..

        1.在頁面中不顯示encode,那麼在servlet中使用getBytes,重新編碼.

 
這是因為:URL中的UTF-8字元------(ISO8859-1)-------->字元數組-------getParameter以
iso8859-1解碼--------->unicode,這裡的UNICODE是不正確的,它是UTF-8編碼的.

  
2.在頁面中顯示encode下,這個過程也可以在servlet中進行,encode(key,"utf-8"),在servlet中不要進行
request.setCharacter(),也就是在servlet中只有iso8859-1與UNICODE間的轉換...到頁面的時候才涉及到本
地符...

-------------------------------------------

關鍵點:對稱的轉換...底層位元組數組的編碼類別型..

相關文章

聯繫我們

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