我感到困惑的是,当我确实在请求中包含参数时,HttpServletRequest.getParameter有时会返回null。
测试程序如下:
HelloServlet.java:
public class HelloServlet extends HttpServlet {
private static Executor logExecutor = Executors.newFixedThreadPool(5);
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
logExecutor.execute(new Task(req));
}
}
class Task implements Runnable {
private HttpServletRequest req;
public Task(HttpServletRequest req) {
this.req = req;
}
@Override
public void run() {
System.out.println(String.format("a=%s b=%s c=%s",
req.getParameter("a"), req.getParameter("b"),
req.getParameter("c")));
}
}
将此servlet映射到web.xml中的/ hello
在tomcat或jetty中启动servlet,使用shell脚本启动请求:
#/bin/sh
for i in {1..100}
do
curl -i -X GET "http://localhost:8080/hello?a=a&b=b&c=c"
done
服务器日志显示某些请求中的某些参数可能为空,并且这种情况是在没有常规模式的情况下发生的。如:
a=a b=b c=c
a=a b=b c=c
a=null b=null c=null
a=null b=null c=null
a=null b=null c=null
a=null b=b c=c
a=null b=null c=c
a=a b=b c=c
a=a b=b c=c
a=a b=b c=c
a=a b=b c=c
a=null b=null c=null
a=a b=b c=c
a=null b=b c=c
我发现原因是我无法为我的执行器保存HttpServletRequest实例。
所以我想知道原因!为什么我在一个请求中持有HttpServletRequest实例的操作可能会影响其他请求。
最佳答案
据我所知,我认为一旦完成请求请求参数就无法访问。
您正在将HttpServletRequest
传递给Thread
。有时,它会在请求完成之前执行,有时会在请求执行之后执行。因此,有时您会得到参数,有时它们是null
。
避免在HttpServletRequest
或doGet
之外处理doPost
。您应该将信息从原始请求复制到单独的数据结构中,以供以后处理。
例如:
public class HelloServlet extends HttpServlet {
private static Executor logExecutor = Executors.newFixedThreadPool(5);
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String data = String.format("a=%s b=%s c=%s",
req.getParameter("a"), req.getParameter("b"),
req.getParameter("c"));
logExecutor.execute(new Task(data));
}
}
class Task implements Runnable {
private String data;
public Task(String data) {
this.data = data;
}
@Override
public void run() {
System.out.println(data);
}
}
编辑:
从Java Servlet Specification中摘录:
3.11请求对象的生存期
每个请求对象仅在servlet的服务方法范围内或在过滤器的doFilter方法范围内有效,
除非为组件启用了异步处理,否则
在请求对象上调用startAsync方法。在这种情况下
在发生异步处理的地方,请求对象仍然有效
直到在AsyncContext上调用complete为止。普通容器
回收请求对象以避免性能开销
请求创建对象。开发人员必须意识到
维护对startAsync还没有的请求对象的引用
不建议在上述范围之外调用它,因为它
可能会有不确定的结果。
关于java - HttpServletRequest.getParameter丢失参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27290524/