HttpServletRequest的getParameter()的坑及解决
作者:我想问问天
HttpServletRequest的getParameter()的坑
问题
最近做项目的时候和对接方联调的时候,对接方会传入一个url给我们,然后经过一系列的操作之后,我们会将一些参数返回到该url上,回调给对接方。
然而当使用了getParameter获取传入的url的时候发现,获取的url并不是对接方传入的完整的url。
例子:对接方传入url=http://abc.com/#/result/success这样类似的url
我们原本要返回的是(a=1&b=2是我方添加的参数):
http://abc.com/#/result/success?a=1&b=2
结果返回的是:
http://abc.com/?a=1&b=2
导致无法达到预期的效果
原因
首先直接贴出来原因,是因为使用了HttpServletRequest下面的getParameter()方法去获取对接方的参数,(类似这样:http://localhost:8090/testGetParam?url=http://abc.com),getParameter(“url”)获取到的url会将"#“后面的内容全部忽略。
因为”#"后的参数已经被忽略了,所以最后返回的时候就只有http://abc.com/?a=1&b=2。
没有了#/result/success这个路径,就使得跳转的页面不正确。
验证过程
我们将通过有没有"#“的对比试验来证明,getParameter()会忽略”#"后面的内容。
1.getParameter()不存在#号的实验:
url: http://localhost:8090/testGetParam?url=http://abc.com
结果:
2.getParameter()存在#号的实验
url: http://localhost:8090/testGetParam?url=http://abc.com/#/index.html
结果:
结论和解决方式
1.有#号和没有#号的结果返回一模一样,因为getParameter()底层把遇到以后#后面的(包括#号自身),全部给忽略掉了,所以导致getParameter时,带有#的内容显示不出来(具体原理后面加文章分析)
2.解决的方式就是采用urlencode,现将url中的#号传入的时候,进行转码,要使用的时候在进行urldecode,就可以了。
HttpServletRequest getParameter为null
HttpServletRequest 提供了 getParameter 方法,可以非常方便获取请求行/请求体中key/value形式的数据(x-www-form-urlencoded、multipart/form-data,其都是key/value形式,只是对数据编码方式有差别),对于application/json 之类的数据只能使用流的方式读取。
创建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 获取参数有如下条件:
1.request.getParameter() 方法获取的参数是形如key/value 形式的数据(x-www-form-urlencoded、multipart/form-data、及请求行中的key1=value1&key2=value2),与数据所在位置(请求体)和请求方法(GET、POST)无关。
2.request.setCharacterEncoding 只能解决post 乱码问题,对于get 方式只能获取到参数值再使用String 相关的转码方式(ISO-8859-1解码)
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。