如何在没有任何请求,会话等的情况下获取上下文?

pet*_*ica 2 java spring tomcat servlets

我在类中有一个方法,它没有得到任何可用于获取实际servlet上下文的方法.实际上,它就像

public String getSomething() { ... }
Run Code Online (Sandbox Code Playgroud)

但是要计算结果,我需要实际的,特定于线程的servlet结构.

我认为,在应用程序上下文的某个深处,某些类似于特定于线程的存储应该存在,这可以通过调用某些系统类的静态方法来实现.

我在一个tomcat6 servlet容器中,但如果需要Spring也可用.

icz*_*cza 8

添加ServletContextListener到您的web.xml.这将在您的webapp加载时调用.在该contextInitialized()方法中,您可以将其存储ServletContext在静态变量中,以供以后使用.然后,您将能够以ServletContext静态方式访问:

class MyListener implements ServletContextListener {

    public static ServletContext context;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        context = sce.getServletContext();
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        context = null;
    }

}
Run Code Online (Sandbox Code Playgroud)

添加web-xml如下:

<web-app>
    <listener>
        <listener-class>
            com.something.MyListener
        </listener-class>
    </listener>
</web-app>
Run Code Online (Sandbox Code Playgroud)

你可以从任何地方访问它:

public String getSomething() {
    // Here you have the context:
    ServletContext c = MyListener.context;
}
Run Code Online (Sandbox Code Playgroud)

注意:

您可能希望将其存储为private并提供getter方法,并null在使用之前检查值.


Ser*_*sta 6

如果您没有指向有用的东西的指针,我知道的唯一方法是在包含当前 ServletContext 的类中拥有静态属性。对于以下内容来说这是微不足道的ServletContextListener

@WebListener
public class ServletContextHolder implements ServletContextListener {
    private static ServletContext servletContext;

    public static ServletContext getServletContext() {
        return servletContext;
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        servletContext = sce.getServletContext();
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        servletContext = null;
    }    
}
Run Code Online (Sandbox Code Playgroud)

然后从您使用的任何地方

ServletContextHolder.getServletContext();
Run Code Online (Sandbox Code Playgroud)

如果您使用 Spring,您还可以使用 来RequestContextHolder访问当前请求(从那里到您需要的任何内容)

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                                 .getRequestAttributes()).getRequest();
Run Code Online (Sandbox Code Playgroud)

当然,如果在 servlet 应用程序中而不是在 portlet 应用程序中以这种方式工作,您将必须使用 PortletRequestAttributes 并最终获得一个 PortletRequest


Kay*_*man 3

一个明显的解决方案是将上下文作为参数传递,因为显然您是在上下文通常可用的地方运行代码。

如果出于某种原因您觉得这不是您可以做的事情(我想听听原因),另一种方法是创建一个 servlet 过滤器,然后创建一个ThreadLocal<ServletContext>.