获取Servlet Context的不同方法

McS*_*onk 22 java servlets

任何人都可以解释一下这种方法之间的区别ServletContextHttpServlet什么?

doGet( HttpServletRequest request, ... ){
    getServletConfig( ).getServletContext( );
    request.getSession( ).getServletContext( );
    getServletContext( );
}
Run Code Online (Sandbox Code Playgroud)

性能或上下文本身有什么不同吗?如果是这样,哪种方式最好?有没有其他方法来检索上下文?

Bal*_*usC 30

还有一个.

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

从技术上讲,性能没有区别,只有在request.getSession()没有创建的情况下才会隐式创建HTTP会话对象.因此,如果尚未完成此操作,那么如果尚未创建会话,则通过会话获取servlet上下文可能需要几纳秒的时间.

返回的上下文也没有区别.这些方法都只是为了方便起见,获取上下文的方法取决于您目前所处的上下文;)

如果你坐在由servlet的调用的方法service()(如doGet(),doPost()等),那么就使用继承的getServletContext()方法.其他方式只是不必要地在源代码中添加更多字符.

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    ServletContext context = getServletContext();
    // ...
}
Run Code Online (Sandbox Code Playgroud)

如果您正坐在servlet的init(ServletConfig)方法中,那么getServletContext()只要您没有调用,继承就不可用super.init(config).你需要抓住它ServletConfig.

@Override
public void init(ServletConfig config) {
    ServletContext context = config.getServletContext();
    // ...
}
Run Code Online (Sandbox Code Playgroud)

但更好的是改写init().在一个体面的servlet中,你通常永远不需要覆盖init(ServletConfig).

@Override
public void init() {
    ServletContext context = getServletContext();
    // ...
}
Run Code Online (Sandbox Code Playgroud)

如果你不是坐在一个servlet中,而是在一个没有继承方法的过滤器中,getServletContext()而你只有ServletRequest手,那么你可以从那里抓住它.

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    ServletContext context = request.getServletContext();
    // ...
}
Run Code Online (Sandbox Code Playgroud)

请注意,这是自Servlet 3.0以来的新功能.以前,您必须从会话中获取它.

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    ServletContext context = request.getSession().getServletContext();
    // ...
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您担心不必要的会话创建,这不是很好.因此引入ServletRequest#getServletContext()- 虽然你也可以简单地从中提取它FilterConfig(嘿,还有另一种方式!).

private FilterConfig config;

@Override
public void init(FilterConfig config) {
    this.config = config;
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    ServletContext context = config.getServletContext();
    // ...
}
Run Code Online (Sandbox Code Playgroud)

然后有HTTP会话侦听器,您可以在其中侦听ao会话销毁.除了via之外,没有其他方法可以获得servlet上下文HttpSession#getServletContext().

@Override
public void sessionDestroyed(HttpSessionEvent event) {
    ServletContext context = event.getSession().getServletContext();
    // ...
}
Run Code Online (Sandbox Code Playgroud)

在这里,您不必担心不必要的会话创建,因为它已经预先创建了很长时间.请注意,没有ServletRequest任何地方,因为在服务器端会话超时期间不一定存在活动HTTP请求.

最后,还会ServletContext#getContext()返回ServletContext部署到同一服务器的不同Web应用程序(仅当服务器配置为在目标Web应用程序上启用跨上下文访问时才有效).

ServletContext otherContext = context.getContext("/otherContextPath");
Run Code Online (Sandbox Code Playgroud)

但是这已经需要从当前ServletContext开始,你现在应该已经知道使用哪种方法来获取它.