获取Servlet上下文的不同方法

36

有人能解释一下通过这两种方式获取 HttpServletServletContext 有什么区别吗?

doGet( HttpServletRequest request, ... ){
    getServletConfig( ).getServletContext( );
    request.getSession( ).getServletContext( );
    getServletContext( );
}

在性能上或者在上下文本身上是否有任何差异?如果有,哪种方法是最好的?还有其他检索上下文的方法吗?


2
没有任何区别。 - user207421
1个回答

46

还有一个。

request.getServletContext();

技术上讲,性能方面没有区别,只有request.getSession()会在未创建HTTP会话对象时隐式创建它。所以如果还没有完成这个操作,那么通过会话获取servlet上下文可能需要多花费几个纳秒,如果会话尚未创建。

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

如果您正在由servlet的service()调用的方法中(例如doGet()doPost()等),则只需使用继承的getServletContext()方法。其他方式只会不必要地增加源代码的字符数。

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

如果您正在servlet的init(ServletConfig)方法中,那么只要您没有调用super.init(config),继承的getServletContext()就还不可用。您需要从ServletConfig中获取它。
@Override
public void init(ServletConfig config) {
    ServletContext context = config.getServletContext();
    // ...
}

但更好的方法是覆盖init()。在一个不错的servlet中,通常不需要覆盖init(ServletConfig)

@Override
public void init() {
    ServletContext context = getServletContext();
    // ...
}

如果您不是在servlet中,而是在一个缺少继承getServletContext()方法的过滤器中,且只有ServletRequest,那么您可以从那里获取它。
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    ServletContext context = request.getServletContext();
    // ...
}

请注意,这是自Servlet 3.0以来的新功能。 以前,您需要从会话中获取它。
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    ServletContext context = request.getSession().getServletContext();
    // ...
}

然而,如果您担心不必要的会话创建,则这种方法并不好。因此引入了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();
    // ...
}

接下来是HTTP会话监听器,你可以监听会话销毁等事件。除了通过HttpSession#getServletContext()方法获取servlet上下文外,没有其他方式。

@Override
public void sessionDestroyed(HttpSessionEvent event) {
    ServletContext context = event.getSession().getServletContext();
    // ...
}

在这里,您不需要担心不必要的会话创建,因为它已经提前很久就被创建了。请注意,在服务器端会话超时期间可能没有活动的HTTP请求,因此不存在ServletRequest
最后,还有ServletContext#getContext(),它返回部署在同一服务器上的不同Web应用程序的ServletContext(仅当服务器配置为在目标Web应用程序上启用跨上下文访问时才起作用)。
ServletContext otherContext = context.getContext("/otherContextPath");

但是这已经需要当前的ServletContext启动,你现在应该已经知道如何获取它了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接