简体   繁体   English

如何从ServletContext获取HttpServletRequest?

[英]How can I get HttpServletRequest from ServletContext?

是否可以从ServletContext获取HttpServletRequest?

Is it possible to get HttpServletRequest from the ServletContext? 是否可以从ServletContext获取HttpServletRequest?

No. 没有。

The ServletContext represents the application. ServletContext代表应用程序。 The application can cover many sessions and requests. 该应用程序可以涵盖许多会话和请求。 But you can't get the "currently running" request or session via the ServletContext . 但是您无法通过ServletContext获得“当前正在运行”的请求或会话。 Detail on how servlets and scopes work can be found in this related answer: How do servlets work? 可以在以下相关答案中找到有关servlet和作用域的详细信息:servlet是如何工作的? Instantiation, sessions, shared variables and multithreading . 实例化,会话,共享变量和多线程

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 . 您显然可以在感兴趣的类的实例中以某种方式使用ServletContext ,而不是HttpServletRequest It's hard to propose an answer showing the right way how to grab the HttpServletRequest in an instance of such class anyway. 无论如何,很难提出一个正确的答案来显示如何在此类实例中获取HttpServletRequest Decent MVC frameworks like JSF and Spring MVC have ways to grab the HttpServletRequest associated with the current thread in any class you want. 像JSF和Spring MVC这样的体面的MVC框架可以通过各种方式来获取与您想要的任何类中的当前线程关联的HttpServletRequest

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. 如果您不使用MVC框架,从而无法使用其功能,则可以通过Servlet过滤器将请求(和响应)作为ThreadLocal<T>在当前线程中,以手动实现。

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

You can create (and close!!) it in a servlet filter as below. 您可以在servlet过滤器中创建(并关闭!!),如下所示。

@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);
    }
}

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. 如果您尚未使用Java 7,因此无法使用上述try-with-resources语句,请使用try-finally块。

Then, in any artifact which is invoked by the same thread/request (ie 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: 然后,在由相同线程/请求调用的任何工件(即,其他过滤器,任何servlet,由这些工件直接调用的任何bean /类(间接)等)中,您都可以获取与当前线程关联的HttpServletRequest ,如下所示:

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();
// ...

As a real world example, Java EE's MVC framework JSF offers exactly this possibility via FacesContext . 作为一个真实的例子,Java EE的MVC框架JSF通过FacesContext提供了这种可能性。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从ServletRequest而不是HTTPServletRequest获取IP地址? - How can I get the IP address from a ServletRequest, not a HTTPServletRequest ? 如何从Tomcat 8中的`HttpServletRequest`获取服务 - How can I get the service from a `HttpServletRequest` in Tomcat 8 如何模拟HttpServletRequest,HttpServletResponse和ServletContext? - How to emulate HttpServletRequest, HttpServletResponse and ServletContext? 如何从WebSocketServlet访问ServletContext? - How can I access ServletContext from WebSocketServlet? 如何在HttpSessionListener中获取HttpServletRequest? - How can I get HttpServletRequest when in an HttpSessionListener? 如何从 HttpServletRequest 中检索 RequestMappingInfo? - How can I retrieve RequestMappingInfo from HttpServletRequest? 如何模拟servletContext而不是Servlet或HttpServletRequest? - how to mock a servletContext instead of Servlet or HttpServletRequest? 如何使用 spring 引导从 HttpServletRequest 获取位置(城市、国家/地区..)? - How can I get the location(city,country.. ) from HttpServletRequest using spring boot? 如何从httpservletrequest获得多部分实体 - How to get multipartentity from httpservletrequest 如何从客户端更改HttpServletRequest中的IP? - How can I change IP in HttpServletRequest from client side?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM