servlet 亂碼問題
1. 亂碼的本質(zhì)
亂碼的本質(zhì)就是文件或者流存的編碼與讀的編碼不一樣洋丐,就會導(dǎo)致亂碼呈昔。
2.常用的編碼
-
gb2312
、gbk
友绝、gb1830
(系統(tǒng)默認編碼堤尾,中國的國標(biāo)碼)
GB2312兼容ASCII碼,這部分還是每個字符占1個字節(jié)迁客。每個漢字字符占2個字節(jié)郭宝。GB2312兼容ASCII碼,這部分還是每個字符占1個字節(jié)掷漱。每個漢字字符占2個字節(jié)
- Unicode(萬國碼粘室,統(tǒng)一碼):
它為每種語言中的每個字符設(shè)定了統(tǒng)一并且唯一的編碼,以滿足跨語言卜范、跨平臺進行文本轉(zhuǎn)換育特、處理的要求。
- utf-8(支持全世界的編碼):
UTF-8對不同范圍的字符使用不同長度的編碼,ASCII編碼部分與ASCII一樣缰冤,都是1個字節(jié)。而漢字部分都是3個字節(jié)喳魏。
- iso-8859-1(不支持中文):
tomcat的默認編碼
3.response響應(yīng)亂碼
3.1: 添加 response.setCharacterEncoding("utf-8");
添加上面語句,發(fā)現(xiàn)客戶端瀏覽器仍然亂碼棉浸。
原因:瀏覽器以默認的編碼解析服務(wù)器編碼的數(shù)據(jù)。
結(jié)論:response.setCharacterEncoding("utf-8");只是告訴tomcat用什么編碼響應(yīng)數(shù)據(jù)刺彩。
3.2: 添加 response.setHeader("content-type", "text/html;charset=UTF-8");
添加上面語句,發(fā)現(xiàn)客戶端瀏覽器成功解決亂碼迷郑。
原因:瀏覽器以與服務(wù)器相同的編碼方式解析。
結(jié)論:response.setHeader("content-type", "text/html;charset=UTF-8");告訴瀏覽器用什么編碼方式解析數(shù)據(jù)创倔。
綜上給出解決response亂碼方案:
response.setHeader("content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("utf-8");
另一種方案:
//告知服務(wù)器用什么碼表編碼嗡害,同時告知瀏覽器用什么碼表解碼。
response.setContentType("text/html;charset=utf-8");
4.request請求亂碼
- post亂碼
瀏覽器發(fā)送post請求時畦攘,瀏覽器使用的什么編碼提交那么post就是什么編碼霸妹。
由于客戶端沒有告訴服務(wù)器,請求正文的編碼知押,于是服務(wù)器默認用ISO-8859-1進行編碼
4.1 添加 request.setCharacterEncoding("utf-8");
成功解決亂碼
原因:訴服務(wù)器請求正文的數(shù)據(jù)應(yīng)該使用的編碼是什么
- get亂碼
瀏覽器發(fā)送get請求時叹螟,瀏覽器使用的什么編碼提交那么get就是什么編碼。
但是當(dāng)請求到達服務(wù)器后台盯,get請求后面的參數(shù)默認使用iso-8859-1進行編碼罢绽。導(dǎo)致亂碼。
4.1 添加 request.setCharacterEncoding("utf-8");
上面代碼執(zhí)行后無效静盅,沒能成功解決亂碼良价。
原因:此種解決方法只對post有效。
4.2
//拿到原始的二進制數(shù)據(jù)蒿叠,用UTF-8進行重新編碼
String name = reuqest.getParameter("name");
byte b[] = name.getBytes("ISO-8859-1");//1010101
String name = new String(b,"UTF-8");//解決
5.另一種解決亂碼的方法
在
tomcat
安裝目錄conf/server.xml
下有如下的配置:
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
我們可以在里面添加一個與編碼有關(guān)的參數(shù)信息:URIEncoding,該配置決定了使用get請求通過瀏覽器地址訪問欄的編碼方式明垢,默認的是iso-8859-1。
在官方文檔中國有說明的:https://tomcat.apache.org/tomcat-7.0-doc/config/http.html
于是我們可以這么配置:
<Connector URIEncoding="utf-8" port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
6.總結(jié)
servlet中的亂碼是由于
tomcat默認的編碼是iso-8859-1 不支持中文
栈虚,使用中文時就會出現(xiàn)問題袖外。解決亂碼也要分情況討論,響應(yīng)或者請求魂务,后者又分為get與post兩種情況曼验,當(dāng)然有時還要考慮數(shù)據(jù)庫亂碼問題。