2017-10-05 203 views
2

我知道页面范围是jsp中的默认范围(与请求/会话/应用程序范围相比,它的权限最小),并且只能在相同的jsp页面中访问对象。jsp中的页面范围

我想知道是否有任何访问相同jsp页面的两个用户共享在页面范围内设置的对象值的可能性?我高度认为答案是否定,但仍想确认一次。

换句话说,PageContext是在两个用户之间共享的吗?如果我使用pageContext.setAttribute(....)将对象设置为页面范围,这个对象是否会在两个不同的用户之间共享?

回答

2

通过查看JSP页面实现类如何使用表示所述范围的PageContext对象,可以更好地理解页面范围的工作方式。

在javadoc for package javax.servlet.jsp中有一个这样做的例子。有趣的部分是:

public void _jspService(HttpServletRequest request, 
         HttpServletResponse response) 
         throws IOException, ServletException { 

    JspFactory factory  = JspFactory.getDefaultFactory(); 
    PageContext pageContext = factory.getPageContext(...) 

    ... 
} 

正如你所看到的,当你的servlet转发的请求和响应对象到JSP,它的页面实现类的_jspService方法被调用,把他们作为参数。紧接着,该方法获得PageContext对象并将其作为该方法的局部变量存储为

局部变量是线程内存(不共享),因此,任何其他线程都无法为另一个用户(甚至不是来自同一用户)的请求提供访问该变量的权限。一旦_jspService返回,变量就不复存在。如果另一个线程同时调用_jspService(),工厂会给它一个不同的PageContext实例。

这会导致从工厂获得的PageContext对象始终是新实例还是正在被重用的问题。这与实施相关,如this question的答案中所述。在后一种情况下,容器应确保它永远不会将同一实例交给两个不同的线程同时(否则会出现并发问题)。

注意,在返回之前,_jspService()确保PageContext对象通过调用releasePageContext任何状态的“清洗”()(参见在Javadoc示例的finally块)。这又会调用PageContext上的release(),其结果是“释放所有内部引用,并准备好可重用的PageContext”。所以,当使用池化实例时,每个线程总是得到一个“干净”的。