我知道页面范围是 jsp 中的默认范围(与请求/ session /应用程序范围相比权限最低),并且只能在同一 jsp 页面中访问对象。
我想知道访问同一 jsp 页面的两个用户是否有可能共享在页面范围内设置的对象值?我强烈觉得答案是否定的,但还是想确认一次。
换句话说,PageContext 是否在两个用户之间共享?如果我使用 pageContext.setAttribute(....) 将对象设置为页面范围,该对象是否会在两个不同的用户之间共享?
最佳答案
通过查看 JSP 页面实现类如何使用表示所述范围的 PageContext
对象,您可以更好地理解页面范围的工作原理。
在包 javax.servlet.jsp 的 javadoc 中有一个例子说明了如何做到这一点。有趣的部分是:
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()
确保通过调用releasePageContext() 来“清除”PageContext
对象的任何状态(请参阅finally javadoc 示例中的
block )。这又调用release()在 PageContext
上,其效果是“释放所有内部引用,并准备 PageContext 以供潜在重用”。因此,当使用池化实例时,每个线程总是获得一个“干净”的实例。
关于jsp - jsp中的页面范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46589394/