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解码)
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
