谁能解释一下这种获得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
开始,为此您现在应该已经知道使用哪种方式来获取它。