編寫此篇文章的原因:前端傳遞參數(shù)帶加號時鹅士,到后端都被轉(zhuǎn)換成了空格券躁,對此問題比較疑惑,進(jìn)行資料查找,發(fā)現(xiàn)編碼方面比較薄弱也拜,進(jìn)行學(xué)習(xí)記錄旭贬。
以上問題解決方法:
URLEncoder.encode("參數(shù)","utf-8");
URLDecoder.decode("參數(shù)","utf-8");
傳遞參數(shù)時進(jìn)行編碼,獲取參數(shù)后進(jìn)行解碼
原因:到現(xiàn)在還比較迷茫搪泳,知道愿意請通知一聲稀轨,謝謝
字符集與編碼方式
字符集(二進(jìn)制與字符的一一映射)
ASCII (最初的字符集)
GB2312--->GBK--->GB18030(各國字符集)
-
Unicode(統(tǒng)一字符集)
? * 為了解決Unicode占用硬盤和流量大的問題產(chǎn)生了相關(guān)編碼方式
- utf-8
- utf-16
url編碼:
-
概念
參考:https://zh.wikipedia.org/wiki/%E7%99%BE%E5%88%86%E5%8F%B7%E7%BC%96%E7%A0%81
URI中允許的字符分為保留字符和非保留字符(RFC 3986中規(guī)定的保留字符和非保留字符)
? 保留字符:! * ' ( ) ; : @ & = + $ , / ? # [ ]
? 非保留字符:AZ,az,09,-_.
如果一個保留字符在特定上下文中具有特殊含義 , 且URI中必須使用該字符用于其它目的, 那么該字符必須百分號編碼.
!
#
$
&
'
(
)
*
+
,
/
:
;
=
?
@
[
]
%21
%23
%24
%26
%27
%28
%29
%2A
%2B
%2C
%2F
%3A
%3B
%3D
%3F
%40
%5B
%5D
-
使用
1.url中的PathInfo
? 實際的url路徑編碼方式由瀏覽器決定
2.url中的QueryString
? 實際的url路徑編碼方式由瀏覽器決定
3.get請求或post 請求Content-Type的值是:application/x-www-form-urlencoded
? 表單提交時笙纤,參數(shù)中中文的編碼則根據(jù)HTML代碼中指定的字符編碼來決定(也就是html代碼中<meta>標(biāo)簽指定的字符編碼)航闺。當(dāng)然這是在form中沒有指定
accept-charset
的情況下,如果form中加了accept-charset="GBK”
屬性异旧,則表單參數(shù)則由accept-charset
指定編碼進(jìn)行編碼
Jsp/Servlet編碼:
-
在jsp/servlet中主要有以下幾個地方可以設(shè)置編碼
-
pageEncoding="UTF-8"
- 設(shè)置jsp編譯成servlet時使用的編碼
- 例如:jsp文件保存為gbk格式艰赞,pageEncoding="UTF-8"時servlet會出現(xiàn)亂碼
- JSP中不指定contentType參數(shù)佣谐,不使用response.setCharacterEncoding方法時,指定對服務(wù)器響應(yīng)進(jìn)行重新編碼的編碼
-
response
需要設(shè)置轉(zhuǎn)換成傳輸流的編碼方式及瀏覽器的解碼方式
服務(wù)器發(fā)給瀏覽器的數(shù)據(jù)默認(rèn)是按照ISO-8859-1編碼方妖,瀏覽器接收到數(shù)據(jù)后按照默認(rèn)的字符集進(jìn)行解碼后顯示狭魂,如果瀏覽器的默認(rèn)解碼字符集不是ISO-8859-1,就出現(xiàn)亂碼党觅。ISO-8859-1不支持中文即傳輸中文必須采用其他傳輸方式雌澄,否則為亂碼
response.setCharacterEncoding("utf-8”);
設(shè)置服務(wù)器端的編碼,默認(rèn)是ISO-8859-1杯瞻;該方法必須在response.getWriter()之前進(jìn)行設(shè)置,如果設(shè)置了Content-Type字段镐牺,response.setCharacterEncoding方法設(shè)置的字符集編碼會出現(xiàn)在Http消息的響應(yīng)頭中,會要求瀏覽器使用utf-8進(jìn)行解碼
response.setHeader("Content-Type", "text/html; ");
或response.setHeader("Content-Type", "text/html;");
通知瀏覽器服務(wù)器發(fā)送的數(shù)據(jù)格式是text/html魁莉,并要求瀏覽器使用utf-8進(jìn)行解碼睬涧。response.setContentType("text/html;charset=utf-8”);
或response.setHeader("Content-Type", "text/html; charset=utf-8”);
它其實會覆蓋response.setCharacterEncoding("utf-8”) ,在開發(fā)中只需要設(shè)置response.setContentType("text/html;charset=utf-8”)就可以了旗唁。意思是通知瀏覽器服務(wù)器發(fā)送的數(shù)據(jù)格式是text/html畦浓,服務(wù)器采用utf-8編碼,并要求瀏覽器使用utf-8進(jìn)行解碼检疫。response.setCharacterEncoding("utf-8”);
設(shè)置服務(wù)器端的編碼為utf-8
response.getWriter().println("<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>”);
要求瀏覽器使用utf-8進(jìn)行解碼,按照整個html格式編寫讶请,寫在head中。
可以看出电谣,第二種方式是最簡便的秽梅,這也是我們在開發(fā)中最常使用的方式。setCharacterEncoding優(yōu)先權(quán)比setContentType及setLocale()節(jié)點要高
-
request
會涉及到URL編程剿牺,參考url編碼
在服務(wù)器端企垦,通過request.setCharacterEncoding("utf-8”)即可設(shè)置服務(wù)器的解碼為utf-8(默認(rèn)是ISO-8859-1),但是它只對請求體里面的參數(shù)有效晒来;如果參數(shù)跟在請求行中的uri后邊钞诡,它就無能為力了。因此請求方式不同,解決亂碼的方案也不同荧降。
-
在地址欄直接輸入URL訪問
編碼方式由瀏覽器決定接箫,RFC 3986協(xié)議強(qiáng)制要求轉(zhuǎn)換為UTF-8,為了方便處理朵诫,通過超鏈接和表單的訪問也規(guī)定必須是utf-8格式辛友,即顯示當(dāng)前頁面的編碼也要使用utf-8,這樣瀏覽器將統(tǒng)一使用utf-8對參數(shù)進(jìn)行編碼
-
點擊頁面中的超鏈接訪問
將參數(shù)按照當(dāng)前頁面的顯示編碼進(jìn)行編碼剪返,RFC 3986協(xié)議強(qiáng)制要求轉(zhuǎn)換為UTF-8废累。
-
提交表單訪問
將參數(shù)按照當(dāng)前頁面的顯示編碼進(jìn)行編碼。
解決方案:
-
post請求
post方式屬于表單提交脱盲,參數(shù)存在于請求體中邑滨,通過request.setCharacterEncoding("utf-8”)即可解決亂碼。
-
get方式
get方式提交的參數(shù)會跟在請求行中的uri后邊钱反,服務(wù)器按照默認(rèn)的iso-8859-1進(jìn)行解碼掖看,這時候解決亂碼有兩種辦法:
-
修改服務(wù)器端對uri參數(shù)的默認(rèn)編碼
在tomcat的server.xml中,設(shè)置<Connector ….>元素的屬性URIEncoding="UTF-8”即可面哥。(默認(rèn)沒有設(shè)置此屬性)
注意:
1哎壳、設(shè)置<Connector ….>元素的屬性useBodyEncodingForURI=“true”,意思是請求體和uri使用相同的編碼格式幢竹。通過設(shè)置這兩個屬性耳峦,既可以解決get方式的亂碼,又可以解決 post方式的亂碼焕毫。
2、通過修改server.xml指定服務(wù)器對get和post統(tǒng)一按照utf-8解碼驶乾,要求tomcat管理下的所有web應(yīng)用都要使用utf-8編碼邑飒,即所有的jsp、html頁面都使用utf-8編碼级乐。比如 JSP頁面的頭信息是這樣的:
<%@ page language="java" contentType="text/html; charset=utf-8"
? pageEncoding="utf-8"%>
-
參數(shù)從瀏覽器到服務(wù)器疙咸,經(jīng)過客戶端utf-8編碼,服務(wù)器端iso-8859-1解碼风科,最終成為亂碼撒轮。那我們將亂碼進(jìn)行相反的編解碼,即可得到正常的參數(shù)值贼穆。
例如:String name = request.getParameter("name”);//得到亂碼
? name = new String(name.getBytes("iso-8859-1"),"utf-8”);//得到正常的name值
? 注意:name.getBytes()题山;如果不指定編碼,默認(rèn)按照gb2312進(jìn)行編碼故痊。
-
?
-
?
-
-