如何从ServletContext获取HttpServletRequest? [英] How can I get HttpServletRequest from ServletContext?

查看:264
本文介绍了如何从ServletContext获取HttpServletRequest?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有可能从ServletContext获取HttpServletRequest?

Is it possible to get HttpServletRequest from the ServletContext?

推荐答案


是吗?可以从ServletContext获取HttpServletRequest吗?

否。

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

The ServletContext represents the application. The application can cover many sessions and requests. But you can't get the "currently running" request or session via the ServletContext. Detail on how servlets and scopes work can be found in this related answer: How do servlets work? Instantiation, sessions, shared variables and multithreading.

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

You're unfortunately not clear on the concrete functional requirement where you need this solution. You apparently have a ServletContext at hands somehow in an instance of the class of interest, but not a HttpServletRequest. It's hard to propose an answer showing the right way how to grab the HttpServletRequest in an instance of such class anyway. Decent MVC frameworks like JSF and Spring MVC have ways to grab the HttpServletRequest associated with the current thread in any class you want.

如果你没有使用MVC框架因此无法使用它的设施,那么你可以通过将请求(和响应)存储为<​​a href =http://docs.oracle来手动实现这一点。当前.com / javase / 8 / docs / api / java / lang / ThreadLocal.htmlrel =nofollow noreferrer> ThreadLocal< T> 线程通过servlet过滤器。

In case you're not using a MVC framework and thus can't use its facilities, then you can achieve this manually by storing the request (and response) as a ThreadLocal<T> in the current thread via a servlet filter.

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

Here's a kickoff example how such a thread local context class can look like:

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).    
}

您可以在维护过滤器如下所示。

@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 块。

Do note that closing is very important. Otherwise the thread will get polluted after it has done its job and will be recycled for a different request or even a completely different purpose. In case you aren't on Java 7 yet and thus can't use try-with-resources statement as above, then use a try-finally block.

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

Then, in any artifact which is invoked by the same thread/request (i.e. other filters, any servlets, any beans/classes (in)directly invoked by those artifacts, etc), you can obtain the HttpServletRequest associated with the current thread as below:

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

或者,更好地创建委托方法,具体取决于你想要处理当前请求,例如获取请求区域设置:

Or, better create a delegate method, depending on whatever you'd like to do with the current request, such as obtaining the request locale:

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

作为一个真实世界的例子,Java EE的MVC框架 JSF 通过 FacesContext

As a real world example, Java EE's MVC framework JSF offers exactly this possibility via FacesContext.

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

这篇关于如何从ServletContext获取HttpServletRequest?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆