亂碼之UTF-8 &GBK


在提交JSP時對於亂碼問題,首先我們要搞清楚為什么會出現亂碼?
看JSP的頭文件:<%@ page contentType="text/html;charset=UTF-8" language="java"%>
在這個頭文件中,還有一個與編碼的相關的屬性:pageEncoding
-----------------------------------------------------------------------------------------
首先,說說JSP/Servlet中的幾個編碼的作用。     
在JSP/Servlet中主要有以下幾個地方可以設置編碼,pageEncoding="UTF-8"、contentType="text/html;charset=UTF-8"、request.setCharacterEncoding("UTF-8")和 response.setCharacterEncoding("UTF-8"),其中前兩個只能用於JSP中,而后兩個可以用於JSP和Servlet 中。
-----------------------------------------------------------------------------------------

request.setCharacterEncoding("UTF-8")的作用是在服務器端設置客戶端請求進行重新編碼的編碼。    

(struts2里面 是在struts.xml 配置<constant name="struts.i18n.encoding" value="UTF-8"></constant>)

      該方法用來指定對瀏覽器發送來的數據進行重新編碼(或者稱為解碼)時,使用的編碼。     
response.setCharacterEncoding("UTF-8")的作用是指定在客戶端對服務器響應進行重新編碼的編碼。     
      服務器在將數據發送到瀏覽器前,對數據進行重新編碼時,使用的就是該編碼。
-----------------------------------------------------------------------------------------
一、瀏覽器是怎么樣對接收和發送的數據進行編碼的 
1.瀏覽器接受數據:
    response.setCharacterEncoding("UTF- 8")的作用是指定對服務器響應進行重新編碼的編碼。同時,瀏覽器也是根據這個參數來對其接收到的數據進行重新編碼(或者稱為解碼)。所以在無論你在 JSP中設置response.setCharacterEncoding("UTF-8")或者 response.setCharacterEncoding("GBK"),瀏覽器均能正確顯示中文。
    讀者可以做個實驗,在JSP中設置response.setCharacterEncoding("UTF-8"),在IE中顯示該頁面時,在IE的菜單中選擇"查看(V)"à"編碼(D)"中可以查看到是" Unicode(UTF-8)",而在在JSP中設置response.setCharacterEncoding("GBK"),在IE中顯示該頁面 時,在IE的菜單中選擇"查看(V)"à"編碼(D)"中可以查看到是"簡體中文(GB2312)"。
2.瀏覽器發送數據:
     瀏覽器在發送數據時,對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。 
--------------------------------------------------------
二、服務器是在接收和發送數據時,是如何對數據進行編碼的
1.服務器發送數據
     對於發送數據,服務器按照response.setCharacterEncoding—contentType—pageEncoding的優先順序,對要發送的數據進行編碼。   
2.服務器接收數據
     對於接收數據,要分三種情況。一種是瀏覽器直接用URL提交的數據,另外兩種是用表單的GET和POST方式提交的數據。     
     因為各種WEB服務器對這三種方式的處理也不相同,所以我們以Tomcat5.0為例。   
     ①對於表單中POST方式提交的數據
     只要在JSP頁面上設置了response.setCharacterEncoding或contentType或pageEncoding為"utf-8",在接受數據的JSP/SERVLET中都不會出現中文亂碼問題。
     ②對於URL提交的數據和表單中GET方式提交的數據
     在接收數據的JSP/SERVLET中僅僅設置request.setCharacterEncoding參數是不行的
     因為在Tomcat5.0中,默認情況下使用ISO-8859-1對URL提交的數據和表單中GET方式提交的數據進行重新編碼(解碼),要解決該問題:     
     應該在Tomcat的配置文件server.xml的Connector標簽中設置useBodyEncodingForURI或者 URIEncoding屬性,其中URIEncoding參數指定對所有GET方式請求(包括URL提交的數據和表單中GET方式提交的數據)進行統一的重新編碼(解碼)的編碼。
     其中useBodyEncodingForURI參數表示是否用request.setCharacterEncoding 參數對URL提交的數據和表單中GET方式提交的數據進行重新編碼,在默認情況下,該參數為false;
     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="UTF-8" 
3、在所有的JSP/Servlet中設置contentType="text/html;charset=UTF-8"或response.setCharacterEncoding("UTF-8"),從而間接實現對瀏覽器編碼的設置。     
4、對於非表單提交的get或url請求,可以修改Tomcat的默認配置,推薦將useBodyEncodingForURI參數設置為true,也可以將URIEncoding參數設置為 UTF-8(有可能影響其他應用,所以不推薦)。或者用下面的方法,在接收數據時處理:
  request.getParameter("userID"),得到userID的值   
  request.getParameter("userID").trim()將這個值去掉兩邊的空格   
  request.getParameter("userID").trim().getBytes("ISO-8859-1"))將這個String用ISO-8859-1編碼成一個字節數祖   
  new   String(request.getParameter("userID").trim().getBytes("ISO-8859-1"),"utf-8")將剛才的字節數祖傳進string的構造函數按照"utf-8"編碼創建一個string對象。 
5.使用URLEncoder的方法
傳參前用: 
//使用指定的編碼機制將字符串轉換為 application/x-www-form-urlencoded 格式
String username_encoder = URLEncoder.encode(username,"UTF-8");
接參數后顯示用:
//使用指定的編碼機制對 application/x-www-form-urlencoded 字符串解碼
String username_decoder = URLDecoder.decode(request.getParameter("username"),"UTF-8");
-----------------------------------------------------------------------------------------
什么是"gbk"?什么是"utf-8"?
一、字符上區分 
  GBK包含全部中文字符; 
  UTF-8則包含全世界所有國家需要用到的字符。
二、編碼上區分 
  GBK是在國家標准GB2312基礎上擴容后兼容GB2312的標准(好像還不是國家標准) 
  UTF-8編碼的文字可以在各國各種支持UTF8字符集的瀏覽器上顯示。 
  例如,如果是UTF8編碼,則在外國人的英文IE上也能顯示中文,而無需他們下載IE的中文語言支持包。所以,對於英文比較多的論壇 ,使用GBK則每個字符占用2個字節,而使用UTF-8英文卻只占一個字節。
三、使用上區分 
  GBK是中國國家編碼,通用性比UTF8差,不過UTF8占用的數據庫比GBK大,而且是一般做論壇的DZ這些程序,對應的組件和插件支持上GBK相應開發的比較全面點,再DIY的時候比較方便。 
  UTF8是國際編碼,它的通用性比較好,外國人也可以瀏覽論壇,而且中文可以直接識別,如果你的論壇要做的比較國際化那就必須用UTF8的。

  補充下:UTF8再繁體支持上比GBK有優勢滴。 
  對於DZ論壇來說,很多插件都只支持GBK的,如果需要裝較多插件的論壇還是用GBK比較好,而對裝較少插件且有特殊用戶群的論壇用UTF8比較好。 
  所以,一般你要是做論壇只是國內的特定圈子里的就用GBK簡單點,基本插件都可以安裝,但是如果你的站有國外的市場需要就建議UTF8了,

Web中文網站開發中,GBK與UTF-8是使用比較多的兩種字符集,但二者是有區別的。總結如下。
1. GBK的文字編碼是雙字節來表示的,即不論中、英文字符均使用雙字節來表示,只不過為區分中文,將其最高位都定成1。
   UTF-8編碼則是用以解決國際上字符的一種多字節編碼,它對英文使用8位(即一個字節),中文使用24位(三個字節)來編碼。對於英文字符較多的論壇則用UTF-8節省空間。
2. GBK包含全部中文字符,包括簡體和繁體字
   UTF-8則包含全世界所有國家需要用到的字符。
3. GBK是在國家標准GB2312基礎上擴容后兼容GB2312的標准(好像還不是國家標准)
   UTF-8編碼的文字可以在各國各種支持UTF8字符集的瀏覽器上顯示。
   比如,如果是UTF8編碼,則在外國人的英文IE上也能顯示中文,而無需他們下載IE的中文語言支持包。 所以,對於英文比較多的論壇 ,使用GBK則每個字符占用2個字節,而使用UTF-8英文卻只占一個字節。

請注意:
   UTF-8版本雖然具有良好的國際兼容性,但中文需要比GBK/BIG5版本多占用50%的數據庫存儲空間,因此並非推薦使用,僅供對國際兼容性有特殊要求的用戶使用。
簡單地說:
   對於中文較多的論壇,適宜用GBK編碼節省數據庫空間。

   對於英文較多的論壇,適宜用UTF-8節省數據庫空間。 

當然 還要記得看服務器mysql字符編碼是怎樣的 畢竟如果很多人用的話 當然還要考慮別人 服務器mysql是utf8所以我們都設置為UTF-8 省事


所以. jsp每次開頭加這段話

<%@ page language="java" contentType="text/html;charset=utf8"  isELIgnored="true" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
	 <base href="<%=basePath%>"/>


版權聲明:本文為博主原創文章,未經博主允許不得轉載。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM