jsp PageContext对象的生命周期是什么 - 它是线程安全的吗?

时间:2012-03-06 09:48:05

标签: jsp thread-safety custom-tags sling servlet-container

jsp PageContext对象是作为http请求 - 响应周期的一部分创建和销毁的,还是在请求之间缓存和重用。

PageContext具有生命周期方法,建议在请求之间重用。即initialize(),release()。

如果它们被重用,这可能会造成严重的并发问题:如果两个http请求到达,请求相同的jsp页面,并且每个请求都由其自己的线程处理,但是在共享的PageContext对象上设置属性,它们将互相呈现'内容。

任何帮助表示赞赏。顺便说一句,我正在使用Apache Sling中嵌入的servlet容器。

2 个答案:

答案 0 :(得分:4)

PageContext只能从您​​的JSP页面获得。如果您的请求首先由servlet处理,然后转发到JSP页面(使用RequestDispatcher.forward),则pageContext仅在此JSP页面上可用,但无法从servlet访问它(因为还没有pageContext那个时候)。

从JSP页面的角度来看,每次调用它时都会获得新的pageContext。页面上下文可以在内部汇集,但不能同时由多个JSP页面共享。

initializerelease方法有这样的评论:“此方法不应由页面或标记库作者使用。”忘了他们。

答案 1 :(得分:3)

Peter is correct. PageContext为处理页面的范围提供了条件。消费者不应该在这个范围之外保留对这些实例的引用,这隐含地意味着实例不应该在当前线程之外访问。

来自JSP 2.2 specification

的JSP处理代码示例
public class foo implements Servlet {
// ...
public void _jspService(HttpServletRequest request, HttpServletResponse response)
               throws IOException, ServletException {
  JspFactory factory = JspFactory.getDefaultFactory();
  PageContext pageContext = factory.getPageContext(
      this,
      request,
      response,
      null, // errorPageURL
      false, // needsSession
      JspWriter.DEFAULT_BUFFER,
      true // autoFlush
    );
  // initialize implicit variables for scripting env ...
  HttpSession session = pageContext.getSession();
  JspWriter out = pageContext.getOut();
  Object page = this;
  try {
    // body of translated JSP here ...
  } catch (Exception e) {
    out.clear();
    pageContext.handlePageException(e);
  } finally {
    out.close();
    factory.releasePageContext(pageContext);
  }
}

如何配置PageContext实例(来自池或实例创建)是容器的实现细节。