从Java代码获取HttpServletRequest(请求)对象

时间:2009-12-04 19:21:05

标签: java servlets

我需要在Java代码中获取请求对象。出于某些原因,我无法将此对象传递给我的代码。有什么方法可以说:getCurrentHTTPServletRequest

我可以安全地假设我处于Servlet环境中。

5 个答案:

答案 0 :(得分:18)

如果你需要,你应该传递它。你做的任何其他事情都会变得很丑陋。

可以使用ThreadLocal变量 - 基本上在你收到请求时设置该特定线程的上下文,然后再获取它。只要您只需要处理正在处理它的线程中的请求,并且只要您不执行任何时髦的异步请求处理,这将起作用。但是,正是因为这些原因,它很脆弱。

但是,我会强烈建议您明确说明您的依赖关系。要么传递servlet请求,要么只传递你需要的位。

答案 1 :(得分:9)

假设你无法将请求对象传递给调用堆栈,那么就需要某种共享机制,这不是理想的,但有时是必要的。

Spring仅为此目的提供了RequestContextFilter。它使用ThreadLocal,并允许代码通过RequestContextHolder获取当前请求。请注意,此过滤器要求您使用Spring的任何其他部分:

  

Servlet 2.3公开的过滤器   请求到当前线程,通过   LocaleContextHolder和   RequestContextHolder。要注册   作为web.xml中的过滤器。

     

此过滤器主要用于   第三方servlet,例如JSF   FacesServlet的。在Spring自己的网站中   支持,DispatcherServlet的   处理就足够了。

如果您要使用ThreadLocal,那么最好使用现有的,有效的解决方案,而不是冒险陷入错误,ThreadLocal代码容易出错。

答案 2 :(得分:4)

Jon Skeet几乎说了一切,但对他的建议做了一个澄清“只需要你需要的部分” - 如果你需要传递请求参数,但是你不需要依赖HttpServletRequest,则传递{ {1}}。

request.getParameterMap()选项上稍微扩展一下 - 你可以有ThreadLocal处理所有传入的请求,并在

中设置请求
Filter

因为您在每个请求上设置它(小心使用过滤器映射),所以您不必担心servlet容器线程池 - 您将始终拥有当前请求。 / p>

P.S。这是skaffman提出的spring实用程序背后的逻辑 - 我和他一起推荐稳定的组件,而不是制作自己的组件。

答案 3 :(得分:4)

没有servlet API可以做到这一点。但是,Tomcat确实提供了一个API调用来执行此操作,

HttpServletRequest request = (HttpServletRequest)org.apache.catalina.core.ApplicationFilterChain.getLastServicedRequest(); 

这会将最后一个请求传递给servlet,以便从当前线程进行维护。

为此,Tomcat必须处于“Strict Servlet Compliance”模式。如果没有,则需要通过添加此JVM参数来启用它:

org.apache.catalina.STRICT_SERVLET_COMPLIANCE=true

答案 4 :(得分:0)

假设顶级servlet确实是一些与业务相关的疯狂原因的禁忌,那么仍然可以选择定义ServletFilter来预先查看请求并将其填充到ThreadLocal中。假设web.xml也不是神圣不可侵犯的。

但我同意Jon Skeet的说法,这会非常难看。我会对此进行编码,然后尝试找一份不同的工作。 :)

实际上,鉴于过滤器可以完全夺走接收servlet的控制权,你可以使用这种技术将代码转移到你自己的servlet,做你想做的任何事情,然后运行另一个,“官方“servlet ......或者其他任何东西。其中一些解决方案甚至可以让您正确,可靠地处理您的请求数据。