Java 如何从ServletContext获取HttpServletRequest?

Java 如何从ServletContext获取HttpServletRequest?,java,servlets,Java,Servlets,是否可以从ServletContext获取HttpServletRequest 是否可以从ServletContext获取HttpServletRequest 没有 表示应用程序。该应用程序可以覆盖许多会话和请求。但是您无法通过ServletContext获取“当前正在运行”的请求或会话。有关servlet和作用域如何工作的详细信息,请参见以下相关答案: 不幸的是,您不清楚需要此解决方案的具体功能需求。显然,您在感兴趣的类的实例中有一个ServletContext,但不是一个。无论如何,很难提出

是否可以从ServletContext获取HttpServletRequest

是否可以从ServletContext获取HttpServletRequest

没有

表示应用程序。该应用程序可以覆盖许多会话和请求。但是您无法通过
ServletContext
获取“当前正在运行”的请求或会话。有关servlet和作用域如何工作的详细信息,请参见以下相关答案:

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

如果您没有使用MVC框架,因此无法使用它的功能,那么您可以通过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).    
}
请注意,结束是非常重要的。否则,线程在完成其工作后将被污染,并将被回收用于不同的请求,甚至完全不同的目的。如果您还没有使用Java 7,因此无法使用上述语句,那么请使用
try finally

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

YourContext context = YourContext.getCurrentInstance();
HttpServletRequest request = context.getRequest();
// ...
或者,最好创建一个委托方法,具体取决于您希望对当前请求执行的操作,例如获取请求区域设置:

YourContext context = YourContext.getCurrentInstance();
Locale requestLocale = context.getRequestLocale();
// ...
作为一个现实世界的例子,JavaEE的MVC框架正是通过提供这种可能性


哪个
HttpServletRequest
?是的,这个。与Tomcat的Http请求相对应的请求。如果有2个请求呢?如果有100个呢?@SotiriosDelimanolis有可能同时有两个请求吗?如果你不能,Servlets将是一个非常糟糕的构建web应用程序的工具。事实上,我使用的是Spring。我调用了需要在不同线程中使用区域设置的逻辑。这才是真正的问题。因此,我不能使用ThreadLocal。然后将其作为方法参数传递。
YourContext context = YourContext.getCurrentInstance();
Locale requestLocale = context.getRequestLocale();
// ...
FacesContext context = FacesContext.getCurrentInstance();
Locale requestLocale = context.getExternalContext().getRequestLocale();
// ...