2012-03-06 46 views
4

jsp PageContext对象是否是作为http请求 - 响应循环的一部分创建和销毁的,还是在请求之间被缓存和重用?jsp PageContext对象的生命周期是什么?它是线程安全的吗?

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

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

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

回答

4

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

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

initializerelease方法有此评论:“此方法不应该由页面或标记库作者使用”。忘掉它们吧。

+0

这是很好的知道,但那么为什么PageContext有生命周期方法,如果它不是回收它们? – murungu 2012-03-06 10:02:55

+0

@murungu:容器可能会使用页面上下文对象池。容器调用这些方法来指示页面上下文使用的开始和结束。页面上下文应该进行必要的初始化或清理。这些方法并不是由JSP页面作者调用的。 – 2012-03-06 10:07:40

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实例是如何配置的(从池或实例创建)是容器的实现细节。

相关问题