还有一个。
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
启动,你现在应该已经知道如何获取它了。