流程處理標籤


當 JSP 網頁必須根據某個條件來安排網頁輸出時,則可以使用流程標籤。例如想要依使用者輸入的名稱、密碼請求參數,來決定是否顯示某個畫面,或是想要用表格輸出十筆資料等。

首先介紹 <c:if> 標籤的使用(假設標籤前置使用 "c"),這個標籤可根據某個運算式的結果,決定是否顯示本體內容。直接來看個範例:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html">
<html>
    <head>
        <meta charset="UTF-8">
        <title>登入頁面</title>
    </head>
    <body>
        <c:if test="${param.name == 'momo' && param.password == '1234'}">
            <h1>${param.name} 登入成功</h1>
        </c:if>
    </body>
</html> 

<c:if> 標籤的test屬性中可以放置 EL 運算式或 JSP 運算元素(<%= %>),如果運算式的結果是 true,則會將 <c:if> 本體輸出。就上面這個範例來說,如果使用者發送的請求參數中,使用者名稱與密碼正確,就會顯示使用者名稱與登入成功的訊息。

<c:if> 標籤僅在 test 的結果為 true 時顯示本體內容,不過並沒有相對應的 <c:else> 標籤。如果想在某條件式成立時顯示某些內容,不成立就顯示另一內容,則可以使用 <c:choose><c:when><c:otherwise> 標籤。同樣以實例來說明:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<jsp:useBean id="user" class="cc.openhome.User"  />
<jsp:setProperty name="user" property="*" />
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>登入頁面</title>
    </head>
    <body>
        <c:choose>
            <c:when test="${user.valid}">
                <h1>
                    <jsp:getProperty name="user" property="name"/>登入成功
                </h1>
            </c:when>
            <c:otherwise>
                 <h1>登入失敗</h1>
            </c:otherwise>
        </c:choose>
    </body>
</html> 

這個範例改寫自〈簡介 〉中的使用者登入網頁範例。在當時使用了 Scriptlet 撰寫 Java 程式碼,判斷使用者是否發送正確名稱密碼,以分別顯示登入成功或失敗的畫面。在學到 <c:choose><c:when><c:otherwise> 標籤之後,就可以不使用 Scriptlet 而實現這個需求。

<c:when><c:otherwise> 必須放在 <c:choose> 之中。當 <c:when>test 運算結果為 true 時,會輸出 <c:when> 的本體內容,而不理會 <c:otherwise> 的內容。<c:choose> 中可以有 多個 <c:when> 標籤,此時會從上往下進行測試,如果有個 <c:when> 標籤的 test 運算結果為 true 就輸出其本體內容,之後的 <c:when> 就不會作測試。如果所有 <c:when> 測試都不成立,則會輸出 <c: otherwise> 的內容。

如果打算使用迴圈來產生一連串的資料輸出。例如你有個簡單的留言版程式,使用 JavaBean 從資料庫中取得留言,留言可能有數十則,以陣列方式傳回:

package cc.openhome;
	
public class MessageService {
    // 放些假資料,假裝這些資料是來自資料庫
    private Message[] fakeMessages = {
         new Message("caterpillar", "caterpillar's message!"),
         new Message("momor", "momor's message!"),
         new Message("hamimi", "hamimi's message!")
    };
    
    public Message[] getMessages() {
        return fakeMessages;
    }
} 

Message 物件有 nametext 屬性,分別表示留言者名稱與留言文字。你打算在網頁上使用表格來顯示每一則留言。若不想使用 Scriptlet 撰寫 Java 程式碼,則可以使用 JSTL 的 <c:forEach> 標籤來實現這項需求。例如:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<jsp:useBean id="messageService" class="cc.openhome.MessageService"/>
<html>
    <head>
        <meta charset="UTF-8">
        <title>留言版</title>
    </head>
    <body>
        <table style="text-align: left; width: 100%;" border="1">
            <tr>
                <td>名稱</td><td>訊息</td>
            </tr>
            <c:forEach var="message" items="${messageService.messages}">
                <tr>
                    <td>${message.name}</td><td>${message.text}</td>
                </tr>
            </c:forEach>
        </table>
    </body>
</html>  

<c:forEach> 標籤的 items 屬性可以是陣列或 Collection 物件,每次會循序取出陣列或 Collection 物件中的一個元素,並指定給var屬性所設定的變數,之後就可以在 <c:forEach> 標籤本體中,使用 var 屬性所設定的變數來取得該元素。

再來簡單地介紹一下 <c:forTokens> 的使用。如果你想要在 JSP 網頁上,將某個字串切割為數個字符(Token),就可以使用 <c:forTokens>。例如:

<c:forTokens  var="token" delims="," items="Java,C++,C,JavaScript">
    ${token} <br>
</c:forTokens>

這個簡單的片段,會將 "Java,C++,C,JavaScript" 這個字串,依指定的 delims 進行切割,所以分出來的字符分別是 "Java""C++""C""JavaScript" 四個字串。