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