2012-03-06 73 views
4

jsp PageContext對象是否是作爲http請求 - 響應循環的一部分創建和銷燬的,還是在請求之間被緩存和重用?jsp PageContext對象的生命週期是什麼?它是線程安全的嗎?

PageContext具有生命週期方法,可以在請求之間建議重用。即initialize(),release()。

如果它們被重用,這可能會造成嚴重的併發問題:如果兩個http請求到達,請求相同的jsp頁面,並且每個請求都由它自己的線程處理,但是在共享PageContext對象上設置屬性,他人的內容。

任何幫助表示讚賞。順便說一下,我正在使用Apache Sling中嵌入的servlet容器。

回答

4

PageContext只能從JSP頁面獲得。如果您的請求首先由servlet處理,然後轉發到JSP頁面(使用RequestDispatcher.forward),則pageContext僅在此JSP頁面上可用,但無法從servlet訪問它(因爲沒有pageContext那時候)。

從JSP頁面的角度來看,每次調用它時都會獲取新的pageContext。頁面上下文可以在內部彙集,但不能同時由多個JSP頁面共享。

initializerelease方法有此評論:「此方法不應該由頁面或標記庫作者使用」。忘掉它們吧。

+0

這是很好的知道,但那麼爲什麼PageContext有生命週期方法,如果它不是回收它們? – murungu 2012-03-06 10:02:55

+0

@murungu:容器可能會使用頁面上下文對象池。容器調用這些方法來指示頁面上下文使用的開始和結束。頁面上下文應該進行必要的初始化或清理。這些方法並不是由JSP頁面作者調用的。 – 2012-03-06 10:07:40

3

Peter is correct.PageContext供應處理頁面的範圍。消費者不應該在這個範圍之外引用這些實例,這隱含地意味着實例不應該在當前線程之外訪問。從JSP 2.2 specification

例JSP處理代碼:

public class foo implements Servlet { 
// ... 
public void _jspService(HttpServletRequest request, HttpServletResponse response) 
       throws IOException, ServletException { 
    JspFactory factory = JspFactory.getDefaultFactory(); 
    PageContext pageContext = factory.getPageContext(
     this, 
     request, 
     response, 
     null, // errorPageURL 
     false, // needsSession 
     JspWriter.DEFAULT_BUFFER, 
     true // autoFlush 
    ); 
    // initialize implicit variables for scripting env ... 
    HttpSession session = pageContext.getSession(); 
    JspWriter out = pageContext.getOut(); 
    Object page = this; 
    try { 
    // body of translated JSP here ... 
    } catch (Exception e) { 
    out.clear(); 
    pageContext.handlePageException(e); 
    } finally { 
    out.close(); 
    factory.releasePageContext(pageContext); 
    } 
} 

PageContext實例是如何配置的(從池或實例創建)是容器的實現細節。

相關問題