有人能解释一下这种获取ServletContext
的{{1}}的方法之间的区别是什么?
HttpServlet
性能或上下文本身有什么不同吗?如果是这样,哪种方式最好?有没有其他方法可以检索上下文?
答案 0 :(得分:27)
还有一个。
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)
方法中,那么只要你没有调用getServletContext()
,继承的super.init(config)
就不可用了。您需要从ServletConfig
抓取它。
@Override
public void init(ServletConfig config) {
ServletContext context = config.getServletContext();
// ...
}
但更好的是覆盖init()
。在一个体面的servlet中,您通常不需要覆盖init(ServletConfig)
。
@Override
public void init() {
ServletContext context = getServletContext();
// ...
}
如果你不是坐在servlet中,而是在例如一个filter缺少继承的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 session listeners你可以在那里听a.o.会话毁灭。获取servlet上下文没有其他方法可以通过HttpSession#getServletContext()
。
@Override
public void sessionDestroyed(HttpSessionEvent event) {
ServletContext context = event.getSession().getServletContext();
// ...
}
在这里,您无需担心不必要的会话创建,因为它已经预先创建了很长时间。请注意,在任何地方都没有ServletRequest
,因为在服务器端会话超时期间不一定有活动的HTTP请求。
最后,还有ServletContext#getContext()
,它返回部署到同一服务器的不同Web应用程序的ServletContext
(仅当服务器配置为在目标webapp上启用跨上下文访问时才有效)。
ServletContext otherContext = context.getContext("/otherContextPath");
但这已经要求当前的ServletContext
开始了,你现在应该知道使用哪种方式来获取它。