2010-08-08 49 views
5

一直困擾着我<jsp:include..>的事情之一是,無法將非字符串值傳遞到包含頁面作爲頁面的不同輸入。例如,我希望能夠做到以下幾點:加強jsp:包含實現

<c:forEach var="item" items="${listOfItems}"> 
    <jsp:include page="mypage.jsp"> 
     <jsp:attribute name="item" value="${item}/> 
    </jsp:include> 
</c:forEach> 

的想法是,通過聲明該項目正在傳遞中作爲JSP中的屬性:包括節點,代碼並明確意圖是什麼......將該參數提供給包含的頁面。

當前唯一可用的機制是定義屬性「全局」,然後讓包含的頁面從全局空間讀取它。不幸的是,這與使用< jsp:param >提供的「意圖」相同。此外,它使代碼更難以調試,因爲任何編程環境中的全局變量都會這樣做。

有沒有人知道執行jsp:include函數的include機制的實現,但是允許傳入非字符串值?或者,如果不是的話,我會接受另外的想法,以保持意圖的相同目標和易於調試。

作爲一個方面說明,我很樂意看到的,當被包含的頁面拋出一​​個錯誤一個內置的「捕獲」機制:

<abc:include page="mypage"> 
    <abc:param name="something" value="some string value"/> 
    <abc:attribute name="somethingelse" value="${nonStringValue}"/> 
    <abc:catch var="ex"> 
     The page failed, so the content it generated will not be sent to the output 
     stream. Instead, we can collapse the part of the page that it's content 
     would be... possibly putting a comment in the page with 
     <!-- There was an exception generating this module: 
      <c:out value="${ex.getMessage}/> 
      --> 
    </abc:catch> 
</abc:include> 

回答

1

已經讀到這裏的答案,再加上做主題更多的研究,我想出了以下內容:

  • 可序列化你的對象,然後反序列化他們在包括JSP。不是這樣的粉絲,因爲它使代碼更復雜(你傳入的每個對象必須是可序列化的等)
  • 您可以使用taglibs。不是這樣的粉絲,因爲我覺得他們的角色不同於JSP包含文件
  • 您可以在請求範圍定義變量,這將使它們可用於包含的JSP。由於它沒有顯示程序員的意圖(將值傳遞給包含的頁面,因爲它僅用於使用),所以不是那麼喜歡它。
  • 確實沒有(我可以找到)實現我正在尋找的實現的實現,但它可能是通過自定義標記構建的。

我做了一些工作,並將代碼放在一起,以實現我正在尋找的內容,然後threw it up on sourceforge。它允許你指定的方式輸入我描述:

<inc:include page="normal.jsp"> 
    <inc:param name="param1" value="param1value" /> 
    <inc:param name="param2" value="param2value" /> 
    <inc:attrib name="attrib1" value="${attrib1value}" /> 
    <inc:attrib name="attrib2" value="${attrib2value}" /> 
    <inc:catch var="ex"> 
     This block was not rolled up because there wasn't an error. 
     Should never see this, but just in case, the exception was: ${ex.message} 
    </inc:catch> 
</inc:include> 

與它唯一的問題(這個時候)是我加的屬性,以包含在頁面之前請求範圍,然後將其刪除之後(或者如果它們已經存在,重置它們)。相反,我想要做的就是包裝請求對象,並覆蓋屬性方法以自動包含傳入的值......我仍在處理這個問題。

+0

因此,我覺得自己的答案是「答案」,但我真的沒有得到我在別處尋找的東西。提供了有用的信息,但我最終不得不將它們結合在一起,並用它來開發我自己的實現。 – RHSeeger 2010-08-13 15:31:37

1

allows for passing in non-String values?

當你被限制到周圍,一個字符串傳遞常見的解決方案是序列化您的對象。

4

從JSTL規範:

Nested scoped variables are only visible within the body of the action and are stored in "page" scope.

可以經由請求範圍傳遞對象的引用。

standardInclude.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 
<c:out value="${foo}" /> 

standardAction.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 
<% 
    //evil scriptlet 
    request.setAttribute("mylist", java.util.Arrays.asList("bar", "baz")); 
%> 
<c:forEach items="${mylist}" var="foo"> 
    <c:set var="foo" scope="request" value="${foo}" /> 
    <jsp:include page="standardInclude.jsp" /> 
    <c:set var="foo" scope="request" value="${null}" /> 
</c:forEach> 

您可以使用catch標籤捕獲異常。

thrower.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 
<c:out value="OK: ${foo}" /> 
<% 
    //evil scriptlet 
    if ("bar".equals(request.getAttribute("foo"))) 
    throw new java.io.IOException("oops"); 
%> 

catcher.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 
<% 
    //evil scriptlet 
    request.setAttribute("mylist", java.util.Arrays.asList("bar", "baz")); 
%> 
<c:forEach items="${mylist}" var="foo"> 
    <br /> 
    <c:set var="foo" scope="request" value="${foo}" /> 
    <c:catch var="ex"> 
     <jsp:include page="thrower.jsp" /> 
    </c:catch> 
    <c:if test="${ex ne null}"> 
     <c:out value="Error for ${foo}" /> 
    </c:if> 
    <c:set var="foo" scope="request" value="${null}" /> 
</c:forEach> 

這將發出:

Error for bar 
OK: baz 
+0

雖然我同意請求範圍確實向「全局範圍較小」方向移動,但它仍然使變量可用的範圍大於它所需的範圍(即當前頁面級別而不是所包含的頁面水平)。另外,它確實解決了意圖問題......它並不表明您將變量專門傳遞到包含的頁面中。在追趕方面,我同意這是一個選擇,但它是醜陋的。 jsp中的整個捕獲機制雖然有用,但還不夠清潔。 – RHSeeger 2010-08-08 20:09:33

+0

通過在包含之後將請求作用域綁定設置爲null,您正在限制其可見性。你要求的是將變量的範圍從一個頁面擴展到另一個頁面。 JSP定義了有限數量的範圍:頁面,參數,請求,會話和應用程序。除非你想進入'ThreadLocal's(蠕蟲的另一個罐頭),這是一樣好。 forEach實現的自定義必須選擇其中一個選項。我建議查看JSP翻譯器生成的Java代碼。它會讓您更好地瞭解您嘗試解決的問題。 – McDowell 2010-08-08 20:39:24

+0

我感興趣的是一個作用域,它使變量對於(其中X包括Y)在Y中可見,但在X中不可見。但是,我想讓X說「這將在Y中可見」,它的方式很多對於包含Y的參數,它看起來應該是可能的,因爲include機制需要爲Y(包含的JSP)創建一個上下文來運行。問題在於,「標準」include-> requestdispatch doesn這是不允許的。因此,我希望有一個自定義的包含標籤(使用自定義的RequestDispatcher)來做到這一點。 – RHSeeger 2010-08-08 20:51:39

0

這可以用JSP標籤被achived文件,而不是包含。有關詳細信息,請參閱我對JSP Component Creation的類似問題的回答。

+0

儘管標記文件可以將對象作爲屬性傳入,但它們的作用與JSP文件不同。尤其是當包含的JSP變得更大時,將其轉換爲標籤似乎打敗了傳達程序員意圖的原始目標。 – RHSeeger 2010-08-08 22:32:25

+0

@RHSeger,你的評論對我來說並不完全清楚,但我認爲在你的第一個例子中,標籤文件是一個更好的解決方案。我使用包含大多數靜態內容,在多個頁面中使用。另一方面,標籤文件對於可變內容很有用,具體取決於它們的參數,然後在同一頁面上多次使用。 – 2010-08-09 07:40:06

+0

忽略我特別提出的示例,並假設我調用了一個JSP並需要傳入實際對象而不是字符串。從那裏開始,包含的JSP可能會包含其他JSP等。根據我的理解,標記文件更多地用於自包含的小型模塊化組件。有沒有可能讓我更詳細地指出標籤文件的文章/描述? – RHSeeger 2010-08-09 13:34:40