从servlet内的线程访问请求对象

时间:2012-07-26 17:52:26

标签: multithreading java-ee servlets

我在servlet中运行此代码

public void doPost(HttpServletRequest request, HttpServletResponse response) {
    final HttpServletRequest requestF = request;
    Runnable runner  = new Runnable() {
       public void run() {
           String something = requestF.getParameter("anything");
           //do other things...
        }
    };
    Thread thread = new Thread(runner);
    thread.start();

但是当我尝试从请求对象中获取参数时,它会抛出异常。

Exception in thread "Thread-25" java.lang.NullPointerException
    at org.apache.catalina.connector.Request.parseParameters(Request.java:2560)
    at org.apache.catalina.connector.Request.getParameter(Request.java:1086)
    at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:355)
    at javax.servlet.ServletRequestWrapper.getParameter(ServletRequestWrapper.java:158)
    at br.com.test.controller.ajax.MyServlet$1.run(MyServlet.java:54)
    at java.lang.Thread.run(Thread.java:619)

requestF对象不为空,我已经检查过了。 有谁知道我是否可以访问新Thread内的请求对象?

2 个答案:

答案 0 :(得分:3)

实际上,请求不是空的。
我怀疑发生的事情是,由于你有一个对请求对象的引用,GC没有收集它。
但是,在处理响应之后,执行了一些关于参数的清理代码(即删除了请求参数的所有条目)。
我想这可能是为了释放内存资源,而不是等待GC,这就是为什么你面临这个空指针异常,这不是由于对请求对象的null访问,而是由于其中一个参数
我建议你获取参数集合,将其复制到一个新的数据结构(即地图)并将其传递给你的线程。
另外,您应该考虑是否希望您的线程在响应发送到客户端之前运行,但这纯粹是一个设计问题。

答案 1 :(得分:2)

是的,Zaske是对的。 您可以使用地图对象的新实例进行复制,如下所示:

final Map<String,String> mapParameters = new HashMap<String,String>();
mapParameters.putAll(request.getParameterMap());

并在“run”方法中使用mapParameters:

public void doPost(HttpServletRequest request, HttpServletResponse response) {
    final Map<String,String> mapParameters = new HashMap<String,String>();
    mapParameters.putAll(request.getParameterMap());
    Runnable runner  = new Runnable() {
       public void run() {
           String something = mapParameters.get("anything");
           //do other things...
       }
    };
    Thread thread = new Thread(runner);
    thread.start();
}