获取 Servlet 上下文的不同方法



谁能解释一下这种获得HttpServlet ServletContext的方式有什么区别?

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

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

还有一个。

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会话侦听器,您可以在其中侦听a.o.会话销毁。除了通过 HttpSession#getServletContext() 之外,没有其他方法可以获取 servlet 上下文。

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

在这里,您无需担心不必要的会话创建,因为它已经提前很久了。请注意,任何地方都没有ServletRequest,因为在服务器端会话超时期间不一定有活动 HTTP 请求。

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

ServletContext otherContext = context.getContext("/otherContextPath");

但这已经需要从当前ServletContext开始,为此您现在应该已经知道使用哪种方式来获取它。

最新更新