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