HttpServletRequest.getParameter丢失参数
我很困惑,HttpServletRequest.getParameter有时会返回null,而我真的在请求中包含参数。HttpServletRequest.getParameter丢失参数
测试下面的程序:
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
开始在Tomcat或码头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);
}
}
编辑:
3。请求对象
每个请求对象是有效的只有一个servlet的服务的方法的范围内,或一个过滤器的doFilter方法, 的范围之内,除非所述异步处理的组分和 启用的11寿命在请求对象上调用startAsync方法。在 发生异步处理的情况下,请求对象保持有效 ,直到在AsyncContext上调用完成为止。 容器通常为 回收请求对象,以避免 请求对象创建的性能开销。显影剂必须意识到 维持引用,以请求其startAsync未 被称为上述的范围外的对象不推荐,因为它 可以具有不确定的结果。
的问题是,你重新声明变量req
在Task
类在这里:
private HttpServletRequest req;
所以在这里你
req
变量甚至没有初始化,并没有任何 做这个servlet请求。此外,我不能看到你在哪里设置这些参数的请求,所以你在哪里设置参数
a,b and c
到请求或req变量?
我很好奇为什么一个HttpServletRequest的实例的值可以由其他请求的影响。 – terry 2014-12-05 07:38:46
我并不是说HttpServletRequest可能会受到另一个的影响。但是一旦请求完成(响应发送给客户端),应用程序服务器(tomcat,jetty ...)就可以清除它的数据。 – 2014-12-05 08:22:16