2017-10-05 71 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」。所以,當使用池化實例時,每個線程總是得到一個「乾淨」的。