【问题标题】:Different ways to get Servlet Context获取 Servlet 上下文的不同方法
【发布时间】:2016-06-20 14:56:01
【问题描述】:

谁能解释一下这种获取ServletContextHttpServlet 的方式有什么区别?

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

性能或上下文本身有什么不同吗?如果是这样,最好的方法是什么?还有其他检索上下文的方法吗?

【问题讨论】:

  • 没有区别。

标签: java servlets


【解决方案1】:

还有一个。

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 中,而是在例如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。会话销毁。除了通过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 开始,您现在应该已经知道使用哪种方式来获取它。

【讨论】:

    猜你喜欢
    • 2012-05-24
    • 1970-01-01
    • 2014-05-22
    • 2015-06-10
    • 2018-09-02
    • 2016-04-27
    • 2016-01-14
    • 2016-06-29
    • 2013-05-07
    相关资源
    最近更新 更多