java学习-http中get请求的非ascii参数如何编码解码探讨
# 背景:
看著別人項(xiàng)目代碼看到一個(gè)PathUtils工具類,
里面只有一個(gè)方法,String? rebuild(String Path),將路徑進(jìn)行URLDecoder.decode解碼,避免路徑中因?yàn)橹形膩y碼導(dǎo)致程序異常
上面的方法的用處是,獲取到項(xiàng)目配置文件的路徑,通過 rebuild?方法返回解碼后的路徑。
?
# 疑惑:
由于我不清楚Path變量是怎么樣的情況,為什么要經(jīng)過rebuild方法過濾一遍
就想測(cè)試下,如果是正常中文進(jìn)行解碼,解碼后的字符串還是一樣的嗎?
String newPath = "Keywords=濕答答";try {newPath = URLDecoder.decode(newPath, "UTF-8");System.out.println(newPath);} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}結(jié)果中文沒有發(fā)生變化。
接著我查看的 URLDecoder的decode方法,? +?號(hào)和 %?開頭的字符串才會(huì)進(jìn)行解碼
note:這里的編碼解碼也稱? ?%百分號(hào)編碼解碼
?
# 深入學(xué)習(xí):
接著,用百度搜索的下 “urldecoder 編碼和解碼”
發(fā)現(xiàn)url編碼解碼主要是應(yīng)用于發(fā)送 http 的 get 請(qǐng)求時(shí),對(duì)特定字符串進(jìn)行編碼,后臺(tái)服務(wù)器會(huì)對(duì)get請(qǐng)求的url進(jìn)行解碼,以保證網(wǎng)絡(luò)傳輸過程中數(shù)據(jù)的正常。
看到一篇文章?不同瀏覽器中URL的編碼方式
?不同瀏覽器對(duì)編碼字符的編碼方式是不同的,
如IE瀏覽器可以設(shè)置編碼的方式
可以設(shè)置是否發(fā)送utf-8格式的url
瀏覽器對(duì)URL編碼方式不一樣可能會(huì)導(dǎo)致我們后臺(tái)獲取到的數(shù)據(jù)是錯(cuò)誤的。
瀏覽器編碼方式有g(shù)bk,utf-8,等等,
假設(shè):瀏覽器使用gbk的編碼方式編碼中文參數(shù)。我們后臺(tái)服務(wù)器接收到后會(huì)進(jìn)行utf-8解碼,因?yàn)榻獯a方式不一樣,就導(dǎo)致我們獲取到的參數(shù)是亂碼的
為了避免這個(gè)問題我們需要自己對(duì)get請(qǐng)求的參數(shù)進(jìn)行url編碼。
?
為什么要自己主動(dòng)對(duì)參數(shù)進(jìn)行編碼呢,需要先大概看下編碼解碼過程
注意:url編碼解碼也稱? ?%百分號(hào)編碼解碼
編碼過程:
字母,特殊用戶字符(/,:@-_.等。即斜杠,逗號(hào),點(diǎn),冒號(hào),橫線,下劃線等)
會(huì)被直接跳過,不會(huì)進(jìn)行編碼處理,
其他的所有字符都要經(jīng)過%xx編碼處理。
encodeURI不編碼字符有82個(gè):!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a-z,A-Z編碼方法很簡(jiǎn)單,在該字節(jié)ascii碼的的16進(jìn)制字符前面加%?
如 空格字符,ascii碼是32,對(duì)應(yīng)16進(jìn)制是'20',那么urlencode編碼結(jié)果是 %20
由于JavaScript使用的是Unicode編碼,也就是utf-8編碼,所以編碼函數(shù)也是使用utf-8編碼,所以js的encodeURI函數(shù),編碼中文,‘愛’? 是三個(gè)字節(jié),編碼后 %e7%88%b1? ,這3個(gè)十六進(jìn)制就代表,愛
?
解碼過程:
解碼是編碼的逆向,對(duì)匹配到的百分號(hào)編碼進(jìn)行反向解碼,字母和特殊字符也會(huì)被跳過。java中會(huì)對(duì)+號(hào)字符進(jìn)行特殊處理,直接用空格替換。
?
上面的編碼和解碼有一個(gè)值得注意的地方,瀏覽器不會(huì)對(duì) +?號(hào)進(jìn)行編碼,而tomcat或jetty服務(wù)器會(huì)將這個(gè)加號(hào)使用空格替換。
如下面的get請(qǐng)求
http://localhost:8080/api/test?aa=zhang+san&p2=18
我們java中使用request.getParameter("aa")方法獲取到的aa參數(shù)的值是zhang san
+?號(hào)被替換成的空格
這是一種情況,用戶輸入,跟我們獲取到的數(shù)據(jù)不一致
?
還有一種情況,服務(wù)器是以 & 符號(hào)進(jìn)行分割參數(shù)的,如果我們把上面+號(hào)替換成&
http://localhost:8080/api/test?aa=zhang&san&p2=18
我們獲取到aa的值是zhang
服務(wù)器會(huì)認(rèn)為這個(gè)get請(qǐng)求有三個(gè)參數(shù),以 & 為分隔符
分別是
aa=zhang
san=
p2=18
?
為了避免以上問題,我們都不應(yīng)該讓瀏覽器對(duì)參數(shù)進(jìn)行編碼,而是我們自己做編碼
?
轉(zhuǎn)載于:https://www.cnblogs.com/gne-hwz/p/10115854.html
總結(jié)
以上是生活随笔為你收集整理的java学习-http中get请求的非ascii参数如何编码解码探讨的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学习OpenGL:笔记一
- 下一篇: L1、L2正则化详解