4

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

PageContext 具有建议在请求之间重用的生命周期方法。即初始化(),释放()。

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

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

4

2 回答 2

4

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

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

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

于 2012-03-06T09:56:44.280 回答
3

彼得是对的。PageContext用于处理页面的范围。消费者不应在此范围之外保留对这些实例的引用,这隐含意味着实例不应在当前线程之外访问。

JSP 2.2 规范中的示例 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实例(从池或实例创建)是容器的实现细节。

于 2012-03-06T10:35:25.723 回答