java - 如何从 ServletContext 获取 HttpServletRequest?

标签 java servlets

是否可以从 ServletContext 获取 HttpServletRequest?

最佳答案

Is it possible to get HttpServletRequest from the ServletContext?

没有。

ServletContext 代表应用程序。该应用程序可以涵盖许多 session 和请求。但是您无法通过 ServletContext 获取“当前正在运行”的请求或 session 。 .有关 servlet 和作用域如何工作的详细信息,请参阅此相关答案:How do servlets work? Instantiation, sessions, shared variables and multithreading .

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

如果您没有使用 MVC 框架,因此无法使用它的功能,那么您可以通过将请求(和响应)存储为 ThreadLocal<T> 来手动实现这一点。在当前线程中通过 servlet 过滤器。

这是一个启动示例,这样的线程本地上下文类看起来像这样:

public final class YourContext implements AutoCloseable {

    private static ThreadLocal<YourContext> 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).    
}

您可以在 servlet filter 中创建(并关闭!!)它如下所示。

@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堵塞。

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

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

或者,最好创建一个委托(delegate)方法,具体取决于您希望对当前请求执行的操作,例如获取请求语言环境:

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

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

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

关于java - 如何从 ServletContext 获取 HttpServletRequest?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31492792/

相关文章:

java - 防止 GUI 卡住并具有取消操作/终止线程的按钮

java - 使用 JAVA 从命令行运行 Symantec End Point DoScan.exe

java - 覆盖整数比较对象?还是骗人?

java - 将来自 Hadoop MapReduce 作业的数据写入 MySQL

java - HTTP Servlet 中的 ArrayList 问题

java - 如何使用来自另一个 JSP 的参数进行查询

java - 如何将搜索过滤器应用到带有分类过滤的回收 View ?

java - 如何在Eclipse项目中导入javax.servlet API?

java - Servlet 中的 cookie 是什么时候创建的?

java - Commons Daemon procrun 标准输出已初始化