Java Web乱码分析及解决方案
1.? 什么是URL編碼。
URL編碼是一種瀏覽器用來打包表單輸入的格式,瀏覽器從表單中獲取所有的name和其對應的value,將他們以name/value編碼方式作為URL的一部分或者分離的發送到服務器上。
?
2.? URL編碼規則。
每對name/value由&分開,每對來自表單的name/value用=分開。如果用戶沒有輸入值的那個name依舊會出現不過就是沒有值。
URL編碼是在字符ASCII碼的十六進制數的前面加上%。例如\(她的十六進制數表示為5c)的URL編碼就是%5c。
?
3.? 簡單介紹亂碼和http請求
其實做web開發亂碼問題是經常出現的,有了上面編碼的基礎之后下面來看看亂碼。
1)? 亂碼問題是web開發過程中經常遇到的問題,主要原因就是URL中使用了非ASCII碼造成服務器后臺程序解析出現亂碼的問題。
2)? URL中最容易出現中文的地方就是在QueryString的參數值還有Servletpath中。
3)? 簡單用一個圖來說明一下http請求的流程:
?
第一步:瀏覽器把URL經過編碼送給服務器;
第二步:服務器把這些請求解碼處理完畢之后將顯示的內容進行編碼發送給客戶端瀏覽器;
第三步:瀏覽器按照指定的編碼顯示網頁
post請求
詳細剖析POST提交如何編碼以及服務器如何解碼以及亂碼解決方案
對于POST方式,表單中的參數值對是通過request包發送給服務器,此時瀏覽器會根據網頁的ContentType("text/html; charset=GBK")中指定的編碼進行對表單中的數據進行編碼,然后發給服務器。
在服務器端的程序中我們可以通過
Request.setCharacterEncoding()設置編碼,然后通過
request.getParameter獲得正確的數據。
這里出現亂碼可以通過Request.setCharacterEncoding()直接解決。
get請求
對于GET方式,我們知道它的提交是將請求數據附加到URL后面作為參數,這樣依賴亂碼就會很容易出現,因為數據name和value很有可能就是傳遞的為非ASCII碼。
當URL拼接后,瀏覽器對其進行encode,然后發送到服務器。具體規則見URL編碼規則。
這里詳細說一下encode的過程中容易出現的問題,在這個過程中我們要明白需要URL encode的字符一般都是非ASCII碼字符,所以我們就能知道出現亂碼主要是URL中附加了中文或特殊字符做成的,另一個要知道URL encode到底是以什么樣的編碼方式對字符進行編碼的,其實這個編碼方式是由瀏覽器決定的,不同的瀏覽器和同一瀏覽器的不同設置影響了URL的編碼,所以為了避免我們不需要的編碼,我們可以通過java代碼或javaspcript代碼統一進行控制。
完成了URL encode之后URL就成了ASCII范圍內的字符了,然后就以iso-8859-1的編碼方式轉換為二進制隨著請求頭一起發送出去。
到了服務器之后,首先服務器會先用iso-8859-1進行解碼,服務器獲取的數據都是ASCII范圍內的請求頭字符,其中請求URL里面帶有參數數據,如果是中衛或特殊字符,那么encode后的%XY(編碼規則中的十六進制數)通過request.setCharacterEncoding()是不管用的。這時候我們就能發現出現亂碼的根本原因就是客戶端一般是通過用UTF-8或GBK等對數據進行encode的,到了服務器卻用iso-8859-1方式decoder顯然不行。
這里的解決方式有兩種,
?通常上,我們的請求都會首先發給Web容器(下面以Tomcat為例),URL也會被Web容器解碼,對于Tomcat容器來說,我們可以在conf/server.xml的connector標簽中增加URL解碼參數,默認容器對URL的使用ISO-8859-1解碼。
?
[html]?view plain?copy?
? ??上面的是Tomcat的默認設定,可以給標簽添加URIEncoding屬性來指定URL的解碼方案。(PS:標簽寫法是URI不是URL)
? ??如果不想使用這種硬解碼方案,還可以指定另一個屬性:useBodyEncodingForURI,這個屬性用來告訴Web容器,如果request指定了解碼方案,則使用request.setCharacterEncoding指定的編碼來解碼URL。
第二種方案沒有經過測試,如果有需要可以嘗試下。詳細資料可以參考下面的Tomcat官方文檔:
http://wiki.apache.org/tomcat/FAQ/CharacterEncoding#Q2
? ??此外,如果不想修改容器的全局配置,畢竟有時候容器里可能不止我們一個應用,那么我們還可以采用下面的做法來提取參數:
?
[java]?view plain?copy
? ??上面的做法,我們要確定Web容器對URL的解碼用的是ISO8859-1,因為不排除其他人修改了容器配置或容器配置本身比較奇葩的可能。
?
總結
以上是生活随笔為你收集整理的Java Web乱码分析及解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaScript程序员必备的5个de
- 下一篇: java美元兑换,(Java实现) 美元