起首,說說JSP和Servlet中的幾個編碼的感化。


在JSP和Servlet中首要有以下幾個處所可以設置編碼,pageEncoding="UTF-8"、contentType="text/html;charset=UTF- 8"、request.setCharacterEncoding("UTF-8")和 response.setCharacterEncoding("UTF-8"),此中前兩個只能用于JSP中,而后兩個可以用于JSP和Servlet中。


1、pageEncoding="UTF-8"的感化是設置JSP編譯成Servlet時應用的編碼。


眾所周知,JSP在辦事器上是要先被編譯成Servlet的。pageEncoding="UTF-8"的感化就是告訴JSP編譯器在將JSP文件編譯成Servlet時應用的編碼。凡是,在JSP內部定義的字符串(直接在JSP中定義,而不是從瀏覽器提交的數據)呈現亂碼時,很多都是因為該參數設置錯誤引起的。例如,你的JSP文件是以GBK為編碼保存的,而在JSP中卻指定pageEncoding="UTF-8",就會引起JSP內部定義的字符串為亂碼。


別的,該參數還有一個功能,就是在JSP中不指定contentType參數,也不應用response.setCharacterEncoding辦法時,指定對辦事器響應進行從頭編碼的編碼。


2、contentType="text/html;charset=UTF-8"的感化是指定對辦事器響應進行從頭編碼的編碼。


在不應用response.setCharacterEncoding辦法時,用該參數指定對辦事器響應進行從頭編碼的編碼。3、request.setCharacterEncoding("UTF-8")的感化是設置對客戶端懇求進行從頭編碼的編碼。


該辦法用來指定對瀏覽器發送來的數據進行從頭編碼(或者稱為解碼)時,應用的編碼。


4、response.setCharacterEncoding("UTF-8")的感化是指定對辦事器響應進行從頭編碼的編碼。


辦事器在將數據發送到瀏覽器前,對數據進行從頭編碼時,應用的就是該編碼。


其次,要說一說瀏覽器是怎么樣對接管和發送的數據進行編碼的


response.setCharacterEncoding("UTF-8")的感化是指定對辦事器響應進行從頭編碼的編碼。同時,瀏覽器也是按照這個參數來對其接管到的數據進行從頭編碼(或者稱為解碼)。所以在無論你在JSP中設置response.setCharacterEncoding("UTF-8")或者 response.setCharacterEncoding("GBK"),瀏覽器均能正確顯示中文(前提是你發送到瀏覽器的數據編碼是正確的,比如正確設置了pageEncoding參數等)。讀者可以做個實驗,在JSP中設置response.setCharacterEncoding("UTF-8"),在IE中顯示該頁面時,在IE的菜單中選擇"查看(V)"à"編碼(D)"中可以查看到是" Unicode(UTF-8)",而在在JSP中設置response.setCharacterEncoding("GBK"),在IE中顯示該頁面時,在IE的菜單中選擇"查看(V)"à"編碼(D)"中可以查看到是"簡體中文(GB2312)"。


瀏覽器在發送數據時,對URL和參數會進行URL編碼,對參數中的中文,瀏覽器也是使 response.setCharacterEncoding參數來進行URL編碼的。以百度和GOOGLE為例,若是你在百度中搜刮"漢字",百度會將其編碼為"%BA%BA%D7%D6"。而在GOOGLE中搜刮"漢字",GOOGLE會將其編碼為"%E6%B1%89%E5%AD%97",這是因為百度的response.setCharacterEncoding參數為GBK,而GOOGLE的的 response.setCharacterEncoding參數為UTF-8。


瀏覽器在接管辦事器數據和發送數據到辦事器時所應用的編碼是雷同的,默認景象下均為JSP頁面的response.setCharacterEncoding參數(或者contentType和pageEncoding參數),我們稱其為瀏覽器編碼。當然,在IE中可以批改瀏覽器編碼(在IE的菜單中選擇"查看(V)"à"編碼(D)"中批改),但凡是景象下,批改該參數會使底本正確的頁面中呈現亂碼。一個有趣的例子是,在IE中瀏覽GOOGLE的主頁時,將瀏覽器編碼批改為"簡體中文(GB2312)",此時,頁面上的中文會變成亂碼,不睬它,在文本框中輸入"漢字",提交,GOOGLE會將其編碼為"%BA%BA%D7%D6",可見,瀏覽器在對中文進行URL編碼時,應用的就是瀏覽器編碼。


弄清了瀏覽器是在接管和發送數據時,是如何對數據進行編碼的了,我們再來看看辦事器是在接管和發送數據時,是如何對數據進行編碼的。


對于發送數據,辦事器遵守response.setCharacterEncoding—contentType—pageEncoding的優先次序,對要發送的數據進行編碼。


對于接管數據,要分三種景象。一種是瀏覽器直接用URL提交的數據,別的兩種是用表單的GET和POST體式格式提交的數據。


因為各類WEB辦事器對這三種體式格式的處理懲罰也不雷同,所以我們以Tomcat5.0為例。


無論應用那種體式格式提交,若是參數中包含中文,瀏覽器都邑應用當前瀏覽器編碼對其進行URL編碼。


對于表單中POST體式格式提交的數據,只要在接管數據的JSP中正確request.setCharacterEncoding參數,即將對客戶端懇求進行從頭編碼的編碼設置成瀏覽器編碼,就可以包管獲得的參數編碼正確。有寫讀者可能會問,那如何獲得瀏覽器編碼呢?上方我們提過了,在默認請景象下,瀏覽器編碼就是你在響應當懇求的JSP頁面中response.setCharacterEncoding設置的值。所以對于POST表單提交的數據,在獲得數據的JSP頁面中request.setCharacterEncoding要和生成提交該表單的JSP頁面的response.setCharacterEncoding設置成雷同的值。


對于URL提交的數據和表單中GET體式格式提交的數據,在接管數據的JSP中設置request.setCharacterEncoding參數是不可的,因為在Tomcat5.0中,默認景象下應用ISO-8859-1對URL 提交的數據和表單中GET體式格式提交的數據進行從頭編碼(解碼),而不應用該參數對URL提交的數據和表單中GET體式格式提交的數據進行從頭編碼(解碼)。要解決該題目,應當在Tomcat的設備文件的Connector標簽中設置useBodyEncodingForURI或者URIEncoding屬性,此中useBodyEncodingForURI參數默示是否用request.setCharacterEncoding參數對URL提交的數據和表單中GET體式格式提交的數據進行從頭編碼,在默認景象下,該參數為false(Tomcat4.0中該參數默認為true);URIEncoding參數指定對所有GET體式格式懇求(包含URL提交的數據和表單中GET體式格式提交的數據)進行同一的從頭編碼(解碼)的編碼。URIEncoding和 useBodyEncodingForURI差別是,URIEncoding是對所有GET體式格式的懇求的數據進行同一的從頭編碼(解碼),而 useBodyEncodingForURI則是按照響應當懇求的頁面的request.setCharacterEncoding參數對數據進行的從頭編碼(解碼),不合的頁面可以有不合的從頭編碼(解碼)的編碼。所以對于URL提交的數據和表單中GET體式格式提交的數據,可以批改URIEncoding 參數為瀏覽器編碼或者批改useBodyEncodingForURI為true,并且在獲得數據的JSP頁面中request.setCharacterEncoding參數設置成瀏覽器編碼。


下面總結下,以Tomcat5.0為WEB辦事器時,如何防止中文亂碼。


1、對于同一個應用,最好同一編碼,推薦為UTF-8,當然GBK也可以。


2、正確設置JSP的pageEncoding參數


3、在所有的JSP和Servlet中設置contentType="text/html;charset=UTF-8"或response.setCharacterEncoding("UTF-8"),從而間接實現對瀏覽器編碼的設置。


4、對于懇求,可以應用過濾器或者在每個JSP和Servlet中設置request.setCharacterEncoding("UTF-8")。同時,要批改Tomcat的默認設備,推薦將 useBodyEncodingForURI參數設置為true,也可以將URIEncoding參數設置為UTF-8(有可能影響其他應用,所以不推薦)。