HttpServletRequest的getParameter()的坑及解決
HttpServletRequest的getParameter()的坑
問題
最近做項(xiàng)目的時(shí)候和對(duì)接方聯(lián)調(diào)的時(shí)候,對(duì)接方會(huì)傳入一個(gè)url給我們,然后經(jīng)過一系列的操作之后,我們會(huì)將一些參數(shù)返回到該url上,回調(diào)給對(duì)接方。
然而當(dāng)使用了getParameter獲取傳入的url的時(shí)候發(fā)現(xiàn),獲取的url并不是對(duì)接方傳入的完整的url。
例子:對(duì)接方傳入url=http://abc.com/#/result/success這樣類似的url
我們?cè)疽祷氐氖?a=1&b=2是我方添加的參數(shù)):
http://abc.com/#/result/success?a=1&b=2
結(jié)果返回的是:
http://abc.com/?a=1&b=2
導(dǎo)致無(wú)法達(dá)到預(yù)期的效果
原因
首先直接貼出來(lái)原因,是因?yàn)槭褂昧薍ttpServletRequest下面的getParameter()方法去獲取對(duì)接方的參數(shù),(類似這樣:http://localhost:8090/testGetParam?url=http://abc.com),getParameter(“url”)獲取到的url會(huì)將"#“后面的內(nèi)容全部忽略。
因?yàn)?rdquo;#"后的參數(shù)已經(jīng)被忽略了,所以最后返回的時(shí)候就只有http://abc.com/?a=1&b=2。
沒有了#/result/success這個(gè)路徑,就使得跳轉(zhuǎn)的頁(yè)面不正確。
驗(yàn)證過程
我們將通過有沒有"#“的對(duì)比試驗(yàn)來(lái)證明,getParameter()會(huì)忽略”#"后面的內(nèi)容。
1.getParameter()不存在#號(hào)的實(shí)驗(yàn):
url: http://localhost:8090/testGetParam?url=http://abc.com
結(jié)果:
2.getParameter()存在#號(hào)的實(shí)驗(yàn)
url: http://localhost:8090/testGetParam?url=http://abc.com/#/index.html
結(jié)果:
結(jié)論和解決方式
1.有#號(hào)和沒有#號(hào)的結(jié)果返回一模一樣,因?yàn)間etParameter()底層把遇到以后#后面的(包括#號(hào)自身),全部給忽略掉了,所以導(dǎo)致getParameter時(shí),帶有#的內(nèi)容顯示不出來(lái)(具體原理后面加文章分析)
2.解決的方式就是采用urlencode,現(xiàn)將url中的#號(hào)傳入的時(shí)候,進(jìn)行轉(zhuǎn)碼,要使用的時(shí)候在進(jìn)行urldecode,就可以了。
HttpServletRequest getParameter為null
HttpServletRequest 提供了 getParameter 方法,可以非常方便獲取請(qǐng)求行/請(qǐng)求體中key/value形式的數(shù)據(jù)(x-www-form-urlencoded、multipart/form-data,其都是key/value形式,只是對(duì)數(shù)據(jù)編碼方式有差別),對(duì)于application/json 之類的數(shù)據(jù)只能使用流的方式讀取。
創(chuàng)建web 項(xiàng)目工程
1.TestServlet.java
package servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class TestServlet */ @WebServlet("/test") public class TestServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); System.out.println("name:" + name); response.getWriter().append("Served at: ").append(request.getContextPath()); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //request.setCharacterEncoding 只能解決post 亂碼問題 request.setCharacterEncoding("utf-8"); doGet(request, response); } }
2.test.jsp 請(qǐng)求核心
fetch('http://localhost:8080/web-test/test?',{ method:'post', body:'name=vincent', headers:{ 'Content-Type':'application/json', } }).then(resp=>{ return resp.text(); }).then(resp=>{ console.log(resp); });
3.效果如下:
4.test.jsp headers Content-Type 修改為:application/x-www-form-urlencoded:
注意
HttpServletRequest getParameter 獲取參數(shù)有如下條件:
1.request.getParameter() 方法獲取的參數(shù)是形如key/value 形式的數(shù)據(jù)(x-www-form-urlencoded、multipart/form-data、及請(qǐng)求行中的key1=value1&key2=value2),與數(shù)據(jù)所在位置(請(qǐng)求體)和請(qǐng)求方法(GET、POST)無(wú)關(guān)。
2.request.setCharacterEncoding 只能解決post 亂碼問題,對(duì)于get 方式只能獲取到參數(shù)值再使用String 相關(guān)的轉(zhuǎn)碼方式(ISO-8859-1解碼)
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(44)
下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧,希望可以幫到你2021-07-07Spring BeanPostProcessor(后置處理器)的用法
這篇文章主要介紹了Spring BeanPostProcessor(后置處理器)的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10servlet生命周期_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了servlet生命周期的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07JAVA統(tǒng)計(jì)字符串中某個(gè)字符出現(xiàn)次數(shù)的方法實(shí)現(xiàn)
本文主要介紹了JAVA統(tǒng)計(jì)字符串中某個(gè)字符出現(xiàn)次數(shù)的方法實(shí)現(xiàn),可以循環(huán)使用String的charAt(int index)函數(shù),具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11SpringBoot使用MockMvc測(cè)試get和post接口的示例代碼
Spring Boot MockMvc是一個(gè)用于單元測(cè)試的模塊,它是Spring框架的一部分,專注于簡(jiǎn)化Web應(yīng)用程序的測(cè)試,MockMvc主要用來(lái)模擬一個(gè)完整的HTTP請(qǐng)求-響應(yīng)生命周期,本文給大家介紹了SpringBoot使用MockMvc測(cè)試get和post接口,需要的朋友可以參考下2024-06-06