jsp中的页面范围
我知道页面范围是jsp中的默认范围(与请求/会话/应用程序范围相比,它的权限最小),并且只能在相同的jsp页面中访问对象。jsp中的页面范围
我想知道是否有任何访问相同jsp页面的两个用户共享在页面范围内设置的对象值的可能性?我高度认为答案是否定,但仍想确认一次。
换句话说,PageContext是在两个用户之间共享的吗?如果我使用pageContext.setAttribute(....)将对象设置为页面范围,这个对象是否会在两个不同的用户之间共享?
通过查看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”。所以,当使用池化实例时,每个线程总是得到一个“干净”的。