如何从ServletContext获取HttpServletRequest?

是否可以从ServletContext获取HttpServletRequest?

是否可以从ServletContext获取HttpServletRequest?

没有。

ServletContext表示应用程序。 该应用程序可以涵盖许多会话和请求。 但是您无法通过ServletContext获取“当前正在运行”的请求或会话。 有关servlet和作用域如何工作的详细信息可以在相关的答案中找到: servlet如何工作? 实例化,会话,共享变量和multithreading 。

遗憾的是,您不清楚需要此解决方案的具体function要求。 你显然在某个感兴趣的类的实例中有一个ServletContext ,但不是HttpServletRequest 。 很难提出一个答案,显示正确的方法如何在这样的类的实例中获取HttpServletRequest 。 像JSF和Spring MVC这样的体面MVC框架有办法在任何你想要的类中获取与当前线程相关的HttpServletRequest

如果您没有使用MVC框架因此无法使用其function,那么您可以通过servletfilter将请求(和响应)作为ThreadLocal在当前线程中来手动实现。

这是一个启动示例,这样的线程本地上下文类如何:

 public final class YourContext implements AutoCloseable { private static ThreadLocal instance = new ThreadLocal<>(); private HttpServletRequest request; private HttpServletResponse response; private YourContext(HttpServletRequest request, HttpServletResponse response) { this.request = request; this.response = response; } public static YourContext create(HttpServletRequest request, HttpServletResponse response) { YourContext context = new YourContext(request, response); instance.set(context); return context; } public static YourContext getCurrentInstance() { return instance.get(); } @Override public void close() { instance.remove(); } // ... (add methods here which return/delegate the request/response). } 

您可以在servletfilter中创建(并关闭!!),如下所示。

 @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; try (YourContext context = YourContext.create(request, response)) { chain.doFilter(request, response); } } 

请注意,收盘非常重要。 否则线程在完成其工作后将受到污染,并将被回收用于不同的请求或甚至完全不同的目的。 如果您还没有使用Java 7,因此无法使用上面的try-with-resources语句,那么请使用try-finally块。

然后,在由同一个线程/请求调用的任何工件(即其他filter,任何servlet,由这些工件直接调用的任何bean / classes(in)等)中,您可以获得与当前线程关联的HttpServletRequest ,如下所示:

 YourContext context = YourContext.getCurrentInstance(); HttpServletRequest request = context.getRequest(); // ... 

或者,更好地创建委托方法,具体取决于您要对当前请求执行的操作,例如获取请求区域设置:

 YourContext context = YourContext.getCurrentInstance(); Locale requestLocale = context.getRequestLocale(); // ... 

作为一个真实世界的例子,Java EE的MVC框架JSF通过FacesContext提供了这种可能性。

 FacesContext context = FacesContext.getCurrentInstance(); Locale requestLocale = context.getExternalContext().getRequestLocale(); // ...