標籤:property strong tomcat page 獲得 tomcat5.0 bytes 設定 asc
0 web.xml中註冊的CharacterEncodingFilter
<!-- 配置字元集過濾器 --><filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param></filter>
上面的配置相當於servlet中的 request.setCharacterEncoding("UTF-8")。
1 post請求
通過jquery.ajax的post請求,不進行request.setCharacterEncoding("UTF-8");也可以收到中文,我發現收到請求後直接request.getCharacterEncoding得到的已經是UTF-8了。查看Request頭部發現含有charset=UTF-8。可能因為要求標頭裡指定了編碼方式,所以將按照這種方式編碼。
而對於form表單的post請求,request.getCharacterEncoding得到的是null,所以需要進行request.setCharacterEncoding。
所以最好都設定上request.setCharacterEncoding("UTF-8");以應付不同的請求。
2 get請求
但是上面的設定方法是針對POST請求的,tomacat對GET和POST請求處理方式是不同的。在Tomcat5.0中,預設情況下使用ISO- 8859-1對URL提交的資料和表單中GET方式提交的資料進行重新編碼(解碼),而不使用request.getCharacterEncoding裡的參數對URL提交的資料和表單中GET方式提交的資料進行重新編碼(解碼)。
要解決該問題(也可以在java後台中用getBytes轉換),應該在Tomcat的設定檔server.xml的Connector標籤中設定useBodyEncodingForURI或者 URIEncoding屬性,其中useBodyEncodingForURI參數表示是否用request.setCharacterEncoding 參數對URL提交的資料和表單中GET方式提交的資料進行重新編碼,在預設情況下,該參數為false(Tomcat4.0中該參數預設為true)。URIEncoding參數指定對所有GET方式請求(包括URL提交的資料和表單中GET方式提交的資料)進行統一的重新編碼(解碼)的編碼。
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>
URIEncoding和useBodyEncodingForURI區別是,URIEncoding是對所有GET方式的請求的資料進行統一的重新編碼(解碼),而useBodyEncodingForURI則是根據響應該請求的頁面的request.setCharacterEncoding參數對資料進行的重新編碼(解碼),不同的頁面可以有不同的重新編碼(解碼)的編碼。所以對於URL提交的資料和表單中GET方式提交的資料,可以修改 URIEncoding參數為瀏覽器編碼或者修改useBodyEncodingForURI為true(這個時候request.setCharacterEncoding為null),並且在獲得資料的JSP頁面中 request.setCharacterEncoding參數設定成瀏覽器編碼。
3 編碼順序
對於發送資料,伺服器按照response.setCharacterEncoding—contentType—pageEncoding的優先順序,對要發送的資料進行編碼。
1、pageEncoding="UTF-8"的作用是設定JSP編譯成Servlet時使用的編碼。
2、contentType="text/html;charset=UTF-8"的作用是指定對伺服器響應進行重新編碼的編碼。
3、request.setCharacterEncoding("UTF-8")的作用是設定對用戶端請求進行重新編碼的編碼。
4、response.setCharacterEncoding("UTF-8")的作用是指定對伺服器響應進行重新編碼的編碼。同時,瀏覽器也是根據這個參數(附在http回應標頭中的charset)來對其接收到的資料進行重新編碼(或者稱為解碼)。Html中meta也有個charset,這個是儲存本地離線網頁時起作用,因為這時沒有方法頭。
值得注意的是,jsp檔案的編碼方式:在JSP標準的文法中,如果 pageEncoding屬性存在,那麼JSP頁面的字元編碼方式就由pageEncoding決定,否則就由contentType屬性中的 charset決定,如果charset也不存在,JSP頁面的字元編碼方式就採用預設的ISO-8859-1(在eclipse中可以自行設定檔的預設編碼方式)。
4 其它
Java編譯時間,jvm按照系統預設(我們常用的運行環境一般為eclipse或者作業系統,eclipse的預設編碼格式可以自己調整;中文作業系統預設使用GBK格式)或者按照指定的字元集(javac –encoding xxx)將源檔案轉化為unicode格式儲存在記憶體中編譯(Java記憶體中採用unicode編碼,一個字元佔兩位元組)。編譯後字元資料會以UNICODE格式存入位元組碼檔案中,產生class檔案。
在運行過程中,JAVA也是採用UNICODE編碼的,並且預設輸入和輸出的都是作業系統的預設編碼。System.getProperty("file.encoding");查看系統預設編碼。
在前端,我們可以用JS指令碼來對參數編碼:encodeURIComponent(),在JAVA端,可以用java.net.URLDecoder.decode來解碼。不過這裡要注意一個問題,就是TOMCAT會自動先對URL 做一次decode,我們可以在TOMCAT的UDecoder類中看到這一點。不過TOMCAT並非使用了URLDecoder.decode,而是自己編寫了一個decode函數。網上有些文章上介紹過一種處理亂碼的方法便是在JS中對參數做兩次encodeURIComponent,在JAVA中做 一次decode,可以解決一些沒有設定URIEncoding時發生的亂碼問題。(解釋如)
5 unicode和utf8
(1) ASCII碼,8位,0到127(包括英文字母、標點等),128到255為擴充ASCII
(2) GBK:16位,一個漢字兩個位元組,一個英文一個位元組
(3) Unicode(統一碼),編碼方案,為全世界每個字元設定唯一的編碼。Unicode目前普遍採用的是UCS-2,它用兩個位元組來編碼一個字元。Unicode也有UCS-4規範,就是用 4個位元組來編碼字元。
(4) utf8:UTF-8是一種unicode的實現方式,它是一種變長的編碼方式。它可以使用1~4個位元組表示一個符號,根據不同的符號而變化位元組長度。,注意的是unicode一個中文字元佔2個位元組,而UTF-8一個中 文字元佔3個位元組)。從unicode到uft-8並不是直接的對應,而是要過一些演算法和規則來轉換。如所示。
例1:“漢”字的Unicode編碼是0x6C49。0x6C49在0x0800-0xFFFF之間,使用用3位元組模板了:1110xxxx 10xxxxxx 10xxxxxx。將0x6C49寫成二進位是:0110 1100 0100 1001, 用這個位元流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89
javaEE中的字元編碼問題