jsp中的页面范围

时间:2017-10-05 15:26:10

标签: jsp pagecontext

我理解页面范围是jsp中的默认范围(与请求/会话/应用程序范围相比最低特权),并且只能在同一个jsp页面中访问对象。

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

在其他方面,PageContext是否在两个用户之间共享?如果我使用pageContext.setAttribute(....)将对象设置为页面范围,那么这个对象是否会在两个不同的用户之间共享?

1 个答案:

答案 0 :(得分:2)

通过查看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对象被“清除”任何状态(请参阅javadoc示例中的finally块)。这反过来调用PageContext上的release(),其效果是“释放所有内部引用,并为可能的重用准备PageContext”。因此,当使用池化实例时,每个线程总是得到一个“干净”的实例。