HttpGet請求與Post請求中參數(shù)亂碼原因剖析與解決方案
1 Get請求
當向服務器發(fā)送請求URL的請求時 :localhost:8080/getinfo?username=張三,通常在服務端中解析username的參數(shù)值時會獲得一串難以解讀的字符信息。
1.1 原因解析
Get請求中的請求參數(shù)會拼接在請求URL中,當URL中存在中文時,瀏覽器會對請求URL進行編碼,其中編碼的時候使用的是UTF-8字符集。Tomcat服務器解析請求發(fā)送的過來的報文時【參數(shù)信息主要是解析請求行的信息】采用的是ISO-8859-1字符集。由于編碼時和解碼時采用的字符集不一致,所以導致了亂碼。
ISO-8859-1字符集,屬于西歐字符集,支持英文、數(shù)字以及標準符號,但是不支持中文字符集。
URL編碼是將每個字符按照編碼方式轉(zhuǎn)為二進制,每個字節(jié)轉(zhuǎn)為2個16進制數(shù)并在前邊加上%
1.2 代碼測試
/** * @Author lyf * @Date 2023/1/11 - 10:43 * @Description URL編解碼 * Get請求亂碼的原因分析 **/ public class URLDemo { public static void main(String[] args) throws UnsupportedEncodingException { String name="張三"; //瀏覽器采用UTF-8對URL編碼 String encode = URLEncoder.encode(name, "UTF-8"); System.out.println("UTF-8編碼"+encode); System.out.println("UTF-8解碼"+ URLDecoder.decode(encode, "UTF-8")); //Tomcat服務器使用ISO-8859-1字符集啊對URL進行解碼 String decode = URLDecoder.decode(encode, "ISO-8859-1"); System.out.println("ISO-8859-1解碼"+ decode); } }
控制臺輸出信息
UTF-8編碼%E5%BC%A0%E4%B8%89
UTF-8解碼張三
ISO-8859-1解碼å¼ ä¸‰
1.3 解決方案
** 值得注意的是,兩種不同的字符集底層的字節(jié)數(shù)組任然是一致的,所以可以考慮先轉(zhuǎn)換成字節(jié) 再將字節(jié)數(shù)組轉(zhuǎn)換為字符串**
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //獲得參數(shù)[存在中文時,utf-8會對其進行編碼,服務器端采用的是iso-0859-1進行的解碼的信息] //該字符串是iso-0859-1解碼后的內(nèi)容 //獲得URL中拼接的參數(shù)值 username String username= req.getParameter("username") //獲得iso-0859-1解碼下的字節(jié)數(shù)組 byte[]bytes=username.getBytes(StandardCharsets.ISO_8859_1); //字節(jié)數(shù)組轉(zhuǎn)成字符串,以UTF-8進行編碼 username=new String(bytes,StandardCharsets.UTF_8); }
值得注意的是,Tomcat8之后已解決Get請求的亂碼的情形,設(shè)置默認的解碼方式為UTF-8。由于req.getParameter()方法是Get 、Post獲取參數(shù)的通用方法。該解決方法同樣也使用于Post請求中參數(shù)亂碼的情況。
2 Post請求
當向服務器發(fā)送Post請求時,同時攜帶參數(shù)信息username=張三時,與Get請求不同的是,參數(shù)不會拼接在請求行中【URL】,而是將參數(shù)信息設(shè)置在請求體中進行傳輸。
2.1 原因解析
通常這種字符型的請求體信息,服務器也是通過獲得字符數(shù)據(jù)來進行解析。req.getReader().readLine()。其中g(shù)etReader()中使用的字符集是ISO-8859-1字符集,不支持中文字符集,因此會亂碼。為了解決中文亂碼,就需要將ISO-8859-1轉(zhuǎn)換為UTF-8字符集,其中需要將請求和響應報文中的字符集都設(shè)置為UTF-8
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //設(shè)置輸入流的編碼 req.setCharacterEncoding("UTF-8"); //設(shè)置輸出流的編碼 resp.setCharacterEncoding("UTF-8"); //獲得請求參數(shù)【post 與 get方法都可以用此方法獲得請求參數(shù)信息】 ,底層邏輯是通過req.getReader().readLine()去獲得請求體中的數(shù)據(jù)來對參數(shù)進行處理的 System.out.println(req.getParameter("username")); }
3 總結(jié)
以上分析可知,導致亂碼的情況可以歸納成輸入的字符集與輸出的字符集不一致的情況,為了解決亂碼的問題,需要將前后的字符集設(shè)置成一致。
到此這篇關(guān)于HttpGet請求與Post請求中參數(shù)亂碼原因剖析與解決方案的文章就介紹到這了,更多相關(guān)HttpGet請求與Post請求參數(shù)亂碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
gliffy-confluence-plugin-9.1.2插件教程詳解
這篇文章主要介紹了gliffy-confluence-plugin-9.1.2破解教程詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02微信支付、支付寶支付等常用第三方支付通道接口手續(xù)費對比
微信支付、支付寶等第三方支付,需要和銀聯(lián)、網(wǎng)聯(lián)對接,有清算機構(gòu)和銀行的交易處理通道成本。費率指支付手續(xù)費的費率,不同行業(yè)、不同的支付平臺、不同的支付額度或次數(shù)所對應的通道費率是不一樣的。2023-01-01Prometheus + Grafana 構(gòu)建強大的監(jiān)控和數(shù)據(jù)可視化系統(tǒng)(最新推薦)
Prometheus?是一個時間序列數(shù)據(jù)庫,但是,它不僅僅是一個時間序列數(shù)據(jù)庫,它涵蓋了可以綁定的整個生態(tài)系統(tǒng)工具集及其功能,非常適合Kubernetes集群的監(jiān)控,這篇文章主要介紹了Prometheus + Grafana 構(gòu)建強大的監(jiān)控和數(shù)據(jù)可視化系統(tǒng),需要的朋友可以參考下2024-05-05將WSL系統(tǒng)更換國內(nèi)源的方法(固定路徑+國內(nèi)鏡像源+詳細教程)
這篇文章主要介紹了將WSL系統(tǒng)更換國內(nèi)源的方法(固定路徑+國內(nèi)鏡像源+詳細教程),首先找到wsl鏡像源,替換鏡像源,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-10-10