HttpServletRequest的getParameter()的坑及解決
HttpServletRequest的getParameter()的坑
問題
最近做項目的時候和對接方聯(lián)調(diào)的時候,對接方會傳入一個url給我們,然后經(jīng)過一系列的操作之后,我們會將一些參數(shù)返回到該url上,回調(diào)給對接方。
然而當(dāng)使用了getParameter獲取傳入的url的時候發(fā)現(xiàn),獲取的url并不是對接方傳入的完整的url。
例子:對接方傳入url=http://abc.com/#/result/success這樣類似的url
我們原本要返回的是(a=1&b=2是我方添加的參數(shù)):
http://abc.com/#/result/success?a=1&b=2
結(jié)果返回的是:
http://abc.com/?a=1&b=2
導(dǎo)致無法達到預(yù)期的效果
原因
首先直接貼出來原因,是因為使用了HttpServletRequest下面的getParameter()方法去獲取對接方的參數(shù),(類似這樣:http://localhost:8090/testGetParam?url=http://abc.com),getParameter(“url”)獲取到的url會將"#“后面的內(nèi)容全部忽略。
因為”#"后的參數(shù)已經(jīng)被忽略了,所以最后返回的時候就只有http://abc.com/?a=1&b=2。
沒有了#/result/success這個路徑,就使得跳轉(zhuǎn)的頁面不正確。
驗證過程
我們將通過有沒有"#“的對比試驗來證明,getParameter()會忽略”#"后面的內(nèi)容。
1.getParameter()不存在#號的實驗:
url: http://localhost:8090/testGetParam?url=http://abc.com
結(jié)果:
2.getParameter()存在#號的實驗
url: http://localhost:8090/testGetParam?url=http://abc.com/#/index.html
結(jié)果:
結(jié)論和解決方式
1.有#號和沒有#號的結(jié)果返回一模一樣,因為getParameter()底層把遇到以后#后面的(包括#號自身),全部給忽略掉了,所以導(dǎo)致getParameter時,帶有#的內(nèi)容顯示不出來(具體原理后面加文章分析)
2.解決的方式就是采用urlencode,現(xiàn)將url中的#號傳入的時候,進行轉(zhuǎn)碼,要使用的時候在進行urldecode,就可以了。
HttpServletRequest getParameter為null
HttpServletRequest 提供了 getParameter 方法,可以非常方便獲取請求行/請求體中key/value形式的數(shù)據(jù)(x-www-form-urlencoded、multipart/form-data,其都是key/value形式,只是對數(shù)據(jù)編碼方式有差別),對于application/json 之類的數(shù)據(jù)只能使用流的方式讀取。
創(chuàng)建web 項目工程
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 請求核心
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、及請求行中的key1=value1&key2=value2),與數(shù)據(jù)所在位置(請求體)和請求方法(GET、POST)無關(guān)。
2.request.setCharacterEncoding 只能解決post 亂碼問題,對于get 方式只能獲取到參數(shù)值再使用String 相關(guān)的轉(zhuǎn)碼方式(ISO-8859-1解碼)
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring BeanPostProcessor(后置處理器)的用法
這篇文章主要介紹了Spring BeanPostProcessor(后置處理器)的用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10servlet生命周期_動力節(jié)點Java學(xué)院整理
這篇文章主要為大家詳細介紹了servlet生命周期的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07JAVA統(tǒng)計字符串中某個字符出現(xiàn)次數(shù)的方法實現(xiàn)
本文主要介紹了JAVA統(tǒng)計字符串中某個字符出現(xiàn)次數(shù)的方法實現(xiàn),可以循環(huán)使用String的charAt(int index)函數(shù),具有一定的參考價值,感興趣的可以了解一下2023-11-11SpringBoot使用MockMvc測試get和post接口的示例代碼
Spring Boot MockMvc是一個用于單元測試的模塊,它是Spring框架的一部分,專注于簡化Web應(yīng)用程序的測試,MockMvc主要用來模擬一個完整的HTTP請求-響應(yīng)生命周期,本文給大家介紹了SpringBoot使用MockMvc測試get和post接口,需要的朋友可以參考下2024-06-06