From Gossip@caterpillar

JSP/Servlet: <jsp: doBody>、<jsp:invoke>與指令元素

 

 


在Tag File中可以使用<jsp:doBody>與<jsp:invoke>動作元素,前者是用來處理標籤本體文字,後者則是用來設 定標籤間的Fragment,這兩個動作元素搭配著attribute與variable兩個指令元素來作示範會比較好說明。

首先介紹<jsp:doBody>您可以用它來決定是否顯示本體文字,例如撰寫如下的Tag File:

  • check.tag
<%@attribute name="password"%> 

<% if(password.equals("1234")) { %>
<jsp:doBody/>
<% } else { %>
密碼不正確
<% } %>

必須先說明的是,這邊使用了Scriptlet,這並不是一個良好的示範,若能搭配JSTL或自訂標籤庫來完成Tag File的撰寫會是比較好的,這邊純綷是為了說明方便才使用了Scriptlet。

上面這個Tag File會檢查傳入的屬性password是否符合我們設定的密碼,如果符合就執行<jsp:doBody>,表示顯示標籤之間的本體文字, 否則顯示密碼不正確的訊息,attribute指令元素可以指定自訂標籤所使用的屬性文字,可以使用下面的JSP網頁來測試:

  • test.jsp
<%@taglib prefix="caterpillar" tagdir="/WEB-INF/tags/" %> 
<html>
<body>
<caterpillar:check password="${ param.pwd }">
您的秘密禮物在此!
</caterpillar:check>
</body>
</html>

您可以發現,Tag File即使是用來當作自訂標籤庫的簡便方式,也是十分的方便,不需要在tld檔中作額外的設定,也可以得到相關的功能。

attribute除了指定屬性文字之外,也可以將屬性當作Fragment傳入,方便在Tag File中作個別的處理,例如下面撰寫一個table.tag:

  • table.tag
<%@attribute name="frag1" fragment="true"%> 
<%@attribute name="frag2" fragment="true"%>

<table border="1">
<tr>
<td><b>frag1</b></td>
<td><jsp:invoke fragment="frag1"/></td>
</tr>
<tr>
<td><b>frag2</b></td>
<td><jsp:invoke fragment="frag2"/></td>
</tr>
</table>


在這個Tag File中,將attribute的屬性設定為Fragment,然後想取得指定的Fragment的話,就可以使用<jsp: invoke>動作元素,並指定Fragment的名稱,使用下面這個JSP網頁來測試:
  • test.jsp
<%@taglib prefix="caterpillar" tagdir="/WEB-INF/tags/" %> 
<html>
<body>
<caterpillar:table>
<jsp:attribute name="frag1">
Fragment 1 here
</jsp:attribute>
<jsp:attribute name="frag2">
Fragment 2 here
</jsp:attribute>
</caterpillar:table>
</body>
</html>

在JSP網頁中,同樣的是使用<jsp:attribute>來說定Fragment的文字內容,執行這個JSP網頁,會傳回以下的內容:
<html>
<body> 
 <table border="1">
   <tr>
       <td><b>frag1</b></td>
       <td>Fragment 1 here</td>
   </tr>
   <tr>
       <td><b>frag2</b></td>
       <td>Fragment 2 here</td>
   </tr>
 </table>
</body>
</html>
 

在Tag File與JSP網頁之間,可以使用variable指令元素設定Scripting Variable,以在兩者之間傳遞變數內容,例如撰寫以下的Tag File:

  • precode.tag
<%@attribute name="preserve" fragment="true" %> 
<%@variable name-given="code" scope="NESTED" %>

<jsp:doBody var="code" />

<table border="1">
<tr>
<td>
<pre><jsp:invoke fragment="preserve"/></pre>
</td>
</tr>
</table>

在這個Tag File中,使用variable設定Scripting Variable為"code",作用範圍為"NESTED",也就是在起始標籤與結束標籤之間,而其中<jsp:doBody>中多了一項 屬性var,表示在JSP網頁中的<jsp:body>標籤中的文字內容將設定給"code"變數,可以用下面這個JSP網頁來測試:
  • test.jsp
<%@ taglib prefix="caterpillar" tagdir="/WEB-INF/tags" %> 
<html>
<body>
<caterpillar:precode>
<jsp:attribute name="preserve">
<b>${ code }</b>
</jsp:attribute>

<jsp:body>
PROGRAM MAIN
PRINT 'HELLO'
END
</jsp:body>
</caterpillar:precode>
</body>
</html>

<jsp:body>之間的虛擬程式碼將會傳入給"code"變數,由於它是Scripting Variable,可以在標籤之內起作用,所以在<jsp:attribute>中的EL式${code}可以取得Tag File中"code"的內容,也就是<jsp:body>傳入的文字,之後我們將<jsp:attribute>的內容當作 Fragment在Tag File中作處理,結果將會如以下的網頁:
<html>
 <body>
 <table border="1">
   <tr>
     <td>
        <pre><b>
 PROGRAM MAIN
    PRINT 'HELLO'
 END
   </b></pre>
     </td>
   </tr>
 </table>
 </body>
</html>