struts2 標籤庫

不設限發表於2011-12-20

第五章:Struts2標籤庫 — Presentation Transcript

  1. 第五章: Struts 2 標籤庫 主講:劉雷
  2. 學習目標
    • Struts2 標籤庫概述
    • Struts2 資料標籤
    • Struts2 控制標籤
    • Struts2 表單標籤
    • Struts2 非表單標籤
  3. Struts2 標籤庫概述
    • Struts2 標籤庫的組成
    • Struts2 框架的標籤庫可以分為以下三類:
      • 使用者介面標籤 (UI 標籤 ) :主要用來生成 HTML 元素的標籤。
        • 表單標籤:主要用於生成 HTML 頁面的 FORM 元素,以及普通表單元素的標籤。
        • 非表單標籤:主要用於生成頁面上的 tree , Tab 頁等。
      • 非使用者介面標籤 ( 非 UI 標籤 ) :主要用於資料訪問,邏輯控制。
        • 資料訪問標籤:主要包含用於輸出值棧 (ValueStack) 中的值,完成國際化等功能的標籤。
        • 流程控制標籤:主要包含用於實現分支,迴圈等流程控制的標籤。
      • AJAX 標籤 : 用於支援 Ajax 效果
  4. Struts2 標籤庫
    • 在早期的 WEB 開發中, JSP 檢視控制和顯示技術主要依靠 Java 指令碼來實現,這樣一來, JSP 頁面重新嵌入了大量的 Java 指令碼程式碼,給開發帶來了極大的不方便。
    • 從 JSP1.1 規範後, JSP 增加了自定義標籤庫的支援。標籤庫是一種元件技術,通過標籤庫,可以將複雜的 Java 指令碼程式碼封裝在元件中,開發者只需要使用簡單的程式碼就可以實現複雜的 Java 指令碼功能。提供了 Java 指令碼的複用性,提高了開發者的開發效率。
    • Struts2 標籤庫相對 struts1.x 進行了巨大的改進,支援 OGNL 表示式,不再依賴任何表現層技術。
  5. Struts2 標籤的使用
    • 我們可以在 struts2-core-2.0.11.jar 壓縮檔案的 META-INF 目錄下找到 struts-tags.tld 檔案,這個檔案裡定義了 Struts2 的標籤。
    • 要在 jsp 中使用 Struts2 的標誌,先要指明標誌的引入。通過 jsp 的程式碼的頂部加入以下的程式碼:
    • <%@taglib prefix=&quot;s&quot; uri=&quot;/struts-tags&quot; %>
  6. Struts2 標籤語法 ( 一 )
    • Struts2 的標籤都支援動態資料的訪問,標籤的屬性都可以使用 OGNL 表示式, struts2 標籤的屬性具有型別,這些型別可以簡單地分為字串型別和非字串型別,對於字串型別的屬性,如果要訪問動態資料,需要使用 %{… } 這樣的語法,
      • 例如: <s:include value=“%{ url }” />
    • Include 標籤的 value 屬性是字串型別, Struts2 將對這個屬性進行解析,查詢符合 %{…} 樣式的字串,然後將花括號之間的內容作為 OGNL 表示式進行求值。如果屬性中沒有 %{…} 樣式的字串,那麼屬性的值將被直接看成是字串資料。
      • 例如: <s:include value=“urlTag.action” />
    • 對於非字串型別的屬性值,將直接作為 OGNL 表示式進行求值。
      • 例如: <s:property value=“username”/>
    • property 標籤的 value 屬性是 Object 型別,它的值 username 將作為 OGNL 表示式進行求值,結果是值棧中位於棧頂的物件的 username 屬性的值。如果要為非字串型別的屬性直接指定字串資料,那麼需要使用 OGNL 中的字串常量,即用單引號(‘)或雙引號(“)將字串括起來。
      • 例如: <s:property value=“’zhangsan‘”/>
      • value 屬性的值‘ zhangsan’ 作為字串常量,計算結果就是 zhangsan ,因此輸出 zhangsan 。
  7. Struts2 標籤語法 ( 二 )
    • 除上述用法之外,也可以使用 %{…} 這樣的語法來指定字串常量。
    • 例如: <s:property value=“%{ ‘zhangsan’ }”/>
    • 在這種情況下, %{ } 將被忽略,花括號中的內容將作為表示式被計算。
    • 總結一下, struts2 標籤的屬性按照下列的三個規則進行計算。
      • (1) 所有的字串屬性型別都會解析“ %{…}” 這樣的語法。
      • (2) 所有的非字元屬性型別都不會被解析,而是直接被看作一個 OGNL 表示式進行求值
      • (3) 對於第二個規則的例外情況是,如果非字串屬性使用了“ %{…}” 語法,那麼 %{…} 將被忽略,花括號中的內容將作為表示式計算。
    • 如果大家在使用標籤時, 忘記了某個屬性是字串型別,還是非字串型別,那麼有一個簡單的方法,那就是不考慮它是什麼型別,統一使用“ %{…}” 語法。
  8. Struts2 通用標籤
    • Struts2 中通用標籤可以分為二類:控制標籤和資料標籤 。控制標籤用於呈現頁面時控制執行流程,資料標籤用於訪問值棧中的資料。
    • 資料標籤: 用於訪問 ActionContext 和值棧中的資料。資料標籤包括:
      • property set push param bean action include
      • url a i18n text date debug
    • 控制標籤: 用於在呈現結果頁面時控制程式的執行流程,根據程式執行的狀態輸出不同的結果,控制標籤包括下列標籤:
      • if/elseif/else iterator append merge
      • generator subset sort
  9. 資料標籤 -----property 標籤
    • property 標籤用於輸出值棧中的物件的屬性 (property) 值,使用 value 屬性來指定要輸出的物件屬性,如果沒有指定 value 屬性,那麼預設輸出棧頂物件。
            • property 標籤屬性
    • 在前面的章節中,我們已經使用過了 property 標籤,我們再看一個例子:
    • <s:property value=“username” default=“ 遊客” />
    • 取出棧頂物件 ( 通常是 action) 的 username 屬性並輸出,如果沒有找到 username 屬性,那麼輸出”遊客”。
  10. 資料標籤 -----set 標籤
    • Set 標籤將一個值賦給指定範圍內變數。 Set 標籤在某些情況下是比較有用的,例如在頁面中多次引用一個複雜的表示式,我們可以將這個表示式賦給一個變數,然後直接引用變數。帶來的好處就是:
      • 提升了效能 ( 表示式的計算只有一次 )
      • 提高了程式碼的可讀性。
            • set 標籤屬性
    • Set 標籤以 name 屬性的值作為鍵 (key) ,將 value 屬性的值儲存到指定的範圍物件中。屬性 scope 取值中的 page,request,session,application 同 JSP 的 4 種範圍,如果指定了 action 範圍 ( 預設值 ) , value 屬性的值將被同時儲存到 request 範圍和 OgnlContext 中。
  11. 示例:訪問地址: http://localhost:8080/.../setTag.action
  12. 資料標籤 -----push 標籤
    • push 標籤用於把一個值壓入值棧 ( 位於棧頂 ) ,注意和 set 標籤的區別, set 標籤是將值放到 action 上下文中。當 push 標籤結束後, push 標籤放入值棧中的物件將被刪除,換句話說,要訪問 push 標籤壓入棧中的物件,需要在標籤內部去訪問。
            • push 標籤的屬性
    public class User { private String username; private String email; private String sex; 省略 set/get 方法 }
  13. Push 標籤示例 訪問: http://localhost:8080/...../pushTag.action
  14. 資料標籤 -----param 標籤
    • param 標籤被用作其他標籤的子標籤,用於為其他標籤提供引數,例如:為 bean 標籤和 include 標籤提供引數。
            • param 標籤的屬性
    • 當使用 param 標籤時, 引數的值可以通過 value 屬性給出,也可以在標籤體中給出 ( 開始標籤和結束標籤之間的文字 ) 。這二種用法有一些區別。我們看下面的例子:
    • <param name=“color”>blue</param> <!-- (1) -->
    • <param name=“color” value=“blue” /> <!-- (2) -->
    • 在第 (1) 種情形中,引數值將作為 java.lang.String 物件 ( 即字串 ) 被放入棧中;
    • 在第 (2) 種情形中,引數值將作為表示式進行計算,如果 blue 不存在,則 color 引數的值為 null 。
    • 在第 (1) 種情形中,要為 color 指定字串值,可以寫為:
    • <param name=“color” value=“ ‘ blue ‘ ”/> 或者 <param name=“color” value=“%{‘ blue ‘ }“/>
    • 使用單引號包圍字串,表明這是一個字串常量
  15. 資料標籤 -----bean 標籤
    • bean 標籤用於例項化一個 JavaBean 物件 ( 必須遵照 JavaBean 規範 ) , bean 標籤的標籤體內可以包含多個 param 標籤,用於設定 Bean 的屬性 ( 必須有相應的 setter 方法 ) 。如果指定了 id 屬性,則建立的 Bean 例項將被放入到 OgnlContext 中。
            • bean 標籤的屬性
    • 注意:
      • id 屬性是可選的,無論是否指定 id 屬性, bean 標籤建立的 JavaBean 例項都會被壓入到值棧的頂部,在 bean 標籤內部可以直接訪問建立的物件,無須使用” #” 標記,當 bean 標籤結束的時候, bean 標籤建立的例項將從值棧中刪除。
      • 如果指定了 id 屬性,那麼 bean 標籤建立的 JavaBean 例項還將被放到 OgnlContext 中,這樣在 bean 標籤的外部,也可以訪問建立的物件了,不過此時就要使用” #” 標記了。
  16. bean 標籤示例
  17. bean 標籤示例說明
    • 在沒有指定 id 屬性的情況下,建立的 User 物件只被壓入值棧,在 bean 標籤的內部使用 property 標籤可以直接訪問 User 物件的屬性。在 bean 標籤外部,由於值棧中的 User 物件已被刪除,所以無法訪問到 User 物件的屬性了。
    • 在指定了 id 屬性的情況下,建立的 User 物件除了被放到值棧中外,還被放到 action 上下文中,因此在標籤的內部和外部都可以訪問 User 物件屬性,只不過在標籤外部訪問時需要新增 #user 字首 ,
    • 訪問路徑: http://localhost:8080/..../beanTag.action
    • 通過指定 action 的名字和可選的名稱空間, action 標籤允許你在 JSP 中直接呼叫 action 。如果將標籤的 excuteResult 屬性設為 true, 那麼 action 對應的結果輸出也將被包含到本頁面中。
    • 在 action 標籤的標籤體中可以巢狀 param 標籤,向 action 傳遞引數。
            • action 標籤的屬性
    資料標籤 -----action 標籤
    • 如果指定了 id 屬性,則 action 將被放到 OgnlContext 中,在 action 標籤結束後,可以通過 #id 來引用 action.
  18. ActionTagAction.java actionTagSuccess.jsp
  19. actionTag.jsp
  20. 示例說明
    • 在第一個 action 標籤呼叫中,執行了結果,但沒有設定 ActiontagAction 的 username 和 email 屬性,所以結果頁面中的這兩項輸出為空。
    • 在第二個 action 標籤呼叫中,不執行結果,呼叫 ActionTagAction 的 doDefault() 方法,在這個方法中,我們在請求物件中設定了 greeting 屬性,在頁面中使用 property 標籤,通過表示式 #attr.greeting 來獲取 greeting 屬性。
    • 在第三個 action 標籤呼叫中,執行了結果,並通過 param 標籤設定了 ActionTagAction 的 username 和 email 屬性,在結果頁面中通過 property 標籤輸出這兩個屬性的值。
    • 訪問路徑: http://localhost:8080/....actionTag.jsp
  21. 資料標籤 -----include 標籤
    • include 標籤類似於 JSP 的 <jsp:include> 標籤,用於包含一個 Servlet 或 JSP 頁面。 include 標籤的標籤體內可以包含多個 param 標籤,用於向被包含的頁面傳遞請求引數
    • include 標籤的屬性
  22. include 標籤示例說明
    • 在 jsp2.jsp 中,我們使用 JSP 的 EL 表示式來獲取傳的請求引數。注意:在 include 標籤內部使用 param 標籤向被包含的頁面傳遞的請求引數, 不能使用如下的 property 標籤來訪問: <s:property value=“#parameters.username” />
    • #parameters 引用的實質是一個 Map 物件,並不等同於 HttpServletRequest 物件。
    • 在包含頁面時,如果頁面中有中文,將會出現亂碼,要解決這個問題,可以在 struts.xml 檔案中配置 struts.i18n.encoding 屬性,如下:
      • <constant name=“struts.i18n.encoding” value=“gbk” />
    • 訪問路徑: http://localhost:8080/.../includeTag.jsp
  23. 資料標籤 -----i18n 和 text 標籤
    • i18n 和 text 標籤用於對國際化提供支援 .i18n 標籤用於將一個資源包放入值棧, text 標籤用於從資源包中獲取訊息。例如
      • <s:i18n name=“ApplicationResources”>
      • <s:text name=“title”/>
      • </s:i18n>
    • i18n 標籤將基名為 ApplicationResources 的資源包放入到值棧中, text 標籤從資源包中獲取鍵為 title 的文字訊息。
    • 注意: i18n 標籤放入值棧的資源包只能在 i18n 標籤的標籤體內訪問,一旦 i18n 標籤結束,值棧中的資源包將被刪除。
    • text 標籤也可以單獨使用,在這種情況下,它將首先查詢資源包的基名與呼叫的 Action 類名相同的資源包。這意味著你可以在 Action 類所在的包中建立與 Action 類名相同的資原始檔,例如:在 com.ibm.action 包中有一個名為 LoginAction 的類, 你可以在 com.ibm.action 包括中建立名為 LoginAction.properties 、 LoginAction_zh.properties 、 LoginAction_en.properties 等資原始檔 ( 名字中的 LoginAction 部分稱為基名 ) ,當執行完 LoginAction 後,在轉向的結果頁面中使用單獨的 text 標籤獲取本地化的文字訊息,那麼 text 標籤將從 com.ibm.action.LoginAction_xx.properties( 根據當前的語言環境選擇某個資原始檔 ) 中讀取 name 屬性值對應的文字訊息。
  24. 資料標籤 -----i18n 和 text 標籤
    • 如果找不到與 Action 類名相同的資源包,那麼就從預設資源包中獲取訊息;如果預設資源包不存在,或者預設資源包中也沒有找到對應的訊息,那麼 text 標籤的標籤體內容將作為預設訊息被輸出;如果沒有標籤體,那麼 name 屬性的值將直接被輸出。
    • text 標籤內部還可以使用巢狀的 param 標籤,來指定訊息文字中的引數, param 標籤的順序對應了訊息文字中引數的索引順序。
            • i18n 標籤的屬性
            • text 標籤的屬性
  25. i18n 和 text 標籤示例
    • 第一步
    • 在專案的 src 下新建包: com.ibm.action, 在這個包中新建 TextTagAction 類,繼承自 ActionSupport 類,注意:你的 Action 類一定要繼承 ActionSupport 類,因為 ActionSupport 類對國際化提供了支援,這樣 text 標籤才能訪問到資源包的基名與你的 Action 類名相同的資源包。
    • TextAction 類沒有任何程式碼,這主要是因為 ActionSupport 基類已經實現了 execute() 方法,該方法返回 Action.SUCCESS, 這就足夠了,我們編寫 TextAction 類的目的是為了通過這個 Action 來訪問使用了 text 標籤的結果頁面。
  26. i18n 和 text 標籤示例
    • 第二步
    • 在 com.ibm.action 包中新建 TextTagAction.properties, 內容如下:
      • username= lisi
      • email= lisi @163. com
      • now=Now is {0} . {1} , welcome you.
      • 鍵為 now 的訊息有兩個引數,分別用 {0} 和 {1} 來表示。
    • 第三步
    • 新建 ApplicationResources.properties, 內容如下:
      • username=zhangsan
      • email=zhangsan@sina.com
  27. i18n 和 text 標籤示例
    • 第四步
  28. 資料標籤 -----date 標籤
    • date 標籤用於格式化輸出日期值,也可用於輸出當前日期值與指定日期值之間的時差
    • date 標籤的屬性
    • 注意:
    • 1 、 format 屬性用於指定日期的格式化樣式,具體的樣式規則可以參看 java.text.SimpleDateFormat 類的 API 文件。
    • 2 、將 nice 屬性設為 true ,可以輸出指定日期值和當前日期值之間的時差,此時 format 屬性失效,也就是說,當 nice 屬性為 true 時,即使你指定了 format 屬性,它也不會起作用
    • 3 、如果沒有使用 nice 屬性,也沒有指定 format 屬性,那麼 date 標籤將會在國際化資源包中查詢 struts.date.format 鍵,並以這個鍵的值作為日期的格式化樣式;如果這個鍵不存在,那麼預設將會使用 DateFormat.MEDIUM 格式化樣式。
    • 4 、如果找不到 name 屬性指定的 Date 物件,那麼將返回空。
  29. date 標籤示例
    • 第一步
    • 在 ApplicationResources.properties 檔案中新增 struts.date.format 鍵
    • struts.date.format=yyyy/MM/dd hh:mm:ss
    • 第二步、
    • 可以使用 struts2 的 struts.custom.i18n.resources 屬性來設定預設的資源包,編輯 struts.xml 檔案,使用 constant 元素來配置 struts.custom.i18n.resources 屬性,內容如下
    • <constant name=“struts.custom.i18n.resources” value=“ApplicationResources”/>
  30. 測試: http://localhost:8080/...../dateTag.jsp
    • 第三步
  31. 控制標籤
    • 控制標籤用於完成流程控制,例如分支,迴圈等操作。控制標籤包含下面幾個:
      • if: 用於控制選擇輸出。
      • elseif: 同 if 標籤結合使用,用來控制選擇輸出。
      • else: 同 if 標籤結合使用,用來控制選擇輸出。
      • append: 用來將多個集合拼接為一個新的集合。
      • generator: 為一個字串解析器,用來將一個字串解析為一個集合。
      • iterator: 迭代器,用來迭代輸出集合資料。
      • merge: 用來將多個集合拼接為一個新的集合 , 同 append 有所區別。
      • sort: 用來對集合排序。
      • subset :用來擷取集合的部分集合,開成新的集合子集合。
  32. 控制標籤 -----if/elseif/else 標籤
    • if/elseif 標籤屬性 test: 為必填屬性,是一個 Boolean 型別值,決定是否顯示 if 標籤內容。該標籤標準格式如下:
        • <s:if test=“ 表示式” >
        • …… ..
        • </s:if>
        • <s:elseif test=“ 表示式” >
        • …… ..
        • </s:elseif>
        • <s:else>
        • ……… ..
        • </s:else>
  33. 控制標籤 ----- if/elseif/else 標籤舉例
    • <%@ taglib prefix=&quot;s&quot; uri=&quot;/struts-tags&quot;%>
    • <!-- 定義一個 testname 屬性 -->
    • <s:set name=&quot;testname&quot; value=&quot;%{'Java'}&quot; />
    • <!-- 使用 if 標籤判斷 -->
    • <s:if test=&quot;%{#testname=='Java'}&quot;>
    • <div>
    • <s:property value=&quot;%{# testname}&quot; />
    • </div>
    • </s:if>
    • <s:elseif test=&quot;%{#testname=='Jav'}&quot;>
    • <div>
    • <s:property value=&quot;%{# testname}&quot; />
    • </div>
    • </s:elseif>
    • <s:else>
    • <div>
    • testname 不是“ Java”
    • </div>
    • </s:else>
  34. 控制標籤 ----- if/elseif/else 標籤舉例
      • <%@ taglib prefix=&quot;s&quot; uri=&quot;/struts-tags&quot;%>
      • <s:set name=&quot;age&quot; value=&quot;61&quot;/>
      • <s:if test=&quot;${age > 60}&quot;>
      •     老年人
      • </s:if>
      • <s:elseif test=&quot;${age > 35}&quot;>
      •     中年人
      • </s:elseif>
      • <s:elseif test=&quot;${age > 15}&quot; id=&quot;wawa&quot;>
      •     青年人
      • </s:elseif>
      • <s:else>
      •     少年
      • </s:else>
  35. 控制標籤 ----- if/elseif/else 標籤舉例
      • <%@ taglib prefix=&quot;s&quot; uri=&quot;/struts-tags&quot;%>
      • <s:set name=&quot;name&quot; value=&quot;<%=&quot;'&quot;+ request.getParameter(&quot;name&quot;)+&quot;'&quot; %>&quot;/>
      • <%
      •   System.out.println(request.getParameter(&quot;name&quot;));
      •   %>
      • <s:if test=&quot;#name=='zhaosoft'&quot;>
      •   zhaosoft here
      • </s:if>
      • <s:elseif test=&quot;#name=='zxl'&quot;>
      •   zxl here
      • </s:elseif>
      • <s:else>
      •   other is here
      • </s:else>
  36. 控制標籤 ----- iterator (迭代標籤)
    • Iterator (迭代)
    • 描述:用於遍歷集合( java.util.Collection ) List,Map, 陣列或列舉值 (java.util.iterator) 。該標籤的屬性如下表:
  37. IteratorStauts 例項包含方法
    • int getCount(): 返回當前迭代過元素的總數。
    • int getIndex(): 返回當前迭代元素的索引。
    • boolean isEven(): 判斷當前迭元素是否為偶數。
    • boolean isOdd(): 判斷當前迭元素是否為奇數。
    • boolean isFirst(): 判斷當前迭元素是否為第一個元素。
    • boolean isLast(): 判斷當前迭元素是否為最後一個元素
    • IteratorStauts 的這些方法分別對應了 count,index,even,odd,first,last 屬性
  38. 控制標籤 ----- iterator 標籤示例
  39. 控制標籤 ----- iterator (迭代標籤)舉例
      • <s:iterator value =&quot;{' 第一個元素 ',' 第二個元素 '}&quot; >
      • <p>day is: <s:property/></p>
      • </s:iterator>
      • private List myList;
      • private Map myMap;
      • public String execute() throws Exception {
      • myList = new ArrayList();
      • myList.add(&quot; 第一個元素 &quot;);
      • myList.add(&quot; 第二個元素 &quot;);
      • myList.add(&quot; 第三個元素 &quot;);
      • myMap = new HashMap();
      • myMap.put(&quot;key1&quot;, &quot; 第一個元素 &quot;);
      • myMap.put(&quot;key2&quot;, &quot; 第二個元素 &quot;);
      • myMap.put(&quot;key3&quot;, &quot; 第三個元素 &quot;);
      • return SUCCESS ;
      • }
      • 省略生成 setter/getter 方法
      • <table>
      • <s:iterator value=&quot;{' 第一個元素 ',' 第二個元素 '}&quot; status=&quot;st&quot;>
      • <tr>
      • <td><s:property value=&quot;#st.getIndex()&quot; /></td>
      • <td><s:property /></td>
      • </tr>
      • </s:iterator>
      • </table>
      • <h2> 顯示 List 屬性 </h2>
      • <table>
      • <s:iterator value=&quot;myList&quot; status=&quot;st&quot;>
      • <tr>
      • <td><s:property value=&quot;#st.getIndex()&quot; /></td>
      • <td><s:property /></td>
      • </tr>
      • </s:iterator>
      • </table>
      • <h2> 顯示 Map</h2>
      • <table>
      • <s:iterator value=&quot;#{'key1':' 第一個元素 ','key2':' 第二個元素 '}&quot; status=&quot;st&quot;>
      • <tr>
      • <td><s:property value=&quot;#st.getIndex()&quot; /></td>
      • <td><s:property /></td>
      • </tr>
      • </s:iterator>
      • </table>
      • <h2> 顯示 Map 屬性 </h2>
      • <table>
      • <s:iterator value=&quot;myMap&quot; status=&quot;st&quot;>
      • <tr>
      • <td><s:property value=&quot;#st.getIndex()&quot; /></td>
      • <td><s:property /></td>
      • </tr>
      • </s:iterator>
      • </table>
  40. 控制標籤 ----- append 標籤
    • append: 用來將多個集合拼接為一個新的集合。這樣拼接的目的就是可以將多個集合使用一個 <iterator /> 標籤完成迭代。標籤屬性 id: 指定了集合元素的 ID 。
    • private List myList1, myList2;
    • private Map myMap1, myMap2;
    • public String execute() throws Exception {
    • myList1 = new ArrayList();
    • myList2 = new ArrayList();
    • myList1.add(&quot; 第一個集合 # 第一個元素 &quot;);
    • myList1.add(&quot; 第一個集合 # 第二個元素 &quot;);
    • myList1.add(&quot; 第一個集合 # 第三個元素 &quot;);
    • myList2.add(&quot; 第二個集合 # 第一個元素 &quot;);
    • myList2.add(&quot; 第二個集合 # 第二個元素 &quot;);
    • myList2.add(&quot; 第二個集合 # 第三個元素 &quot;);
    • myMap1 = new HashMap(); myMap2 = new HashMap();
    • myMap1.put(&quot;key1&quot;, &quot; 第一個集合 # 第一個元素 &quot;);
    • myMap1.put(&quot;key2&quot;, &quot; 第一個集合 # 第二個元素 &quot;);
    • myMap1.put(&quot;key3&quot;, &quot; 第一個集合 # 第三個元素 &quot;);
    • myMap2.put(&quot;key1&quot;, &quot; 第二個集合 # 第一個元素 &quot;);
    • myMap2.put(&quot;key2&quot;, &quot; 第二個集合 # 第二個元素 &quot;);
    • myMap2.put(&quot;key3&quot;, &quot; 第二個集合 # 第三個元素 &quot;);
    • return SUCCESS;
    • } // 省略 setter/getter 方法
    • <h1><span style=&quot;background-color: #FFFFcc&quot;>Append 標籤示例 </span></h1>
    • <h2> 拼接 List 屬性 </h2>
    • <table>
    • <s:append id=&quot;newList&quot;>
    • <s:param value=&quot;myList1&quot; />
    • <s:param value=&quot;myList2&quot; />
    • </s:append>
    • <s:iterator value=&quot;#newList&quot; id=&quot;name&quot; status=&quot;st&quot;>
    • <tr>
    • <td><s:property value=&quot;#st.getIndex()&quot; /></td>
    • <td><s:property /></td>
    • </tr>
    • </s:iterator>
    • </table>
    • <h2> 拼接 Map 屬性 </h2>
    • <table>
    • <s:append id=&quot;newMap&quot;>
    • <s:param value=&quot;myMap1&quot; />
    • <s:param value=&quot;myMap2&quot; />
    • </s:append>
    • <s:iterator value=&quot;#newMap&quot; status=&quot;st&quot;>
    • <tr>
    • <td><s:property value=&quot;#st.getIndex()&quot; /></td>
    • <td><s:property /></td>
    • </tr>
    • </s:iterator>
    • </table>
  41. 控制標籤 ----- generator 標籤
    • generator 標籤用來將指定的字串按規定的分隔符分解為多個子字串,生成的多個子字串可以使用 iterator 標籤輸出。
    • 該標籤的屬性如下:
      • id: 指定了集合元素的 ID 。
      • count :可選屬性,為一個 Integer 型別值,指定生成集合中元素的總數。
      • separator: 必填屬性,為一個 String 型別值,指定用來分解字串的分隔符。
      • val :必填屬性,為一個 String 型別值,指定被分解的字串。
      • converter :可選屬性,為一個 Converter 型別例項,指定一個轉換器,該轉換器負責將集合中的每個字串轉換為物件。
  42. 控制標籤 ----- generator 標籤舉例
    • private String msg;
    • public String getMsg() {
    • return msg;
    • }
    • public void setMsg(String msg) {
    • this.msg = msg;
    • }
    • public String execute() throws Exception {
    • setMsg(&quot; 第一個元素 ; 第二個元素 ; 第三個元素 &quot;);
    • return SUCCESS;
    • }
  43. 控制標籤 ----- generator 標籤舉例
    • <h1>
    • <span style=&quot;background-color: #FFFFCC&quot;>Generator 標籤示例 </span>
    • </h1>
    • <table>
    • <s:generator separator=&quot;;&quot; val=&quot;msg&quot; id=&quot;temp&quot; count=&quot;2&quot;></s:generator>
    • <s:iterator status=&quot;st&quot; value=&quot;#attr.temp&quot;>
    • <tr>
    • <td><s:property value=&quot;#st.getIndex()&quot; /></td>
    • <td><s:property /></td>
    • </tr>
    • </s:iterator>
    • </table>
    • 注意:如果在 generator 標籤中指定了 count 屬性,則該集合中最多隻能有 count 個元素,多餘的元素將會被忽略。
  44. 控制標籤 ----- append 標籤
    • append: 用來將多個集合拼接為一個新的集合。
  45. 控制標籤 ----- merge 標籤
    • Merge 標籤用於合併迭代器,其用法與 append 相似,區別就是對合並後的迭代器中的元素迭代的順序不一樣。
  46. 控制標籤 ----- subset 標籤
    • Subset 標籤用於擷取一個迭代器的子集,其內部實現是通過 org.apache.struts2.util.SubsetIteratorFilter 類來完成的。
  47. Subset 標籤示例
  48. subset 標籤示例
    • 除了上面的用法之外,還可以使用 subset 屬性指定一個 Decider ,用於過濾某些元素。要編寫一個 Decider 類,需要實現 org.apache.struts2.util.SubsetIteratorFilter.Decider 介面,該介面只有一個方法, public boolean decide(Object element) throw Exception, 如果該方法返回 true ,表明引數 element 表示的元素應該被包含到子集中。
    • 我們編寫一個 Decider 類,選取集合中含有“ java” 子串的元素,程式碼如下:
    首先使用 bean 標籤例項化 MyDecider 物件,並將這個物件放入到 OgnlContext 中。在 subset 標籤的 decider 屬性中,通過 OGNL 表示式 #myDecider 來引用 MyDecider 物件。
  49. 控制標籤 ----- sort 標籤
    • Sort 標籤根據 comparator 屬性指定的比較器對集合進行排序,並將排序後的迭代器壓入值棧的棧頂。在 sort 標籤的內部,你可以使用 iterator 標籤取出棧頂的迭代器對排序後的元素進行迭代。當 sort 標籤結束時,棧頂的迭代器將被刪除。
  50. sort 標籤示例
  51. 表單標籤
    • Struts2 的表單標籤可以分為兩類, form 標籤本身和包裝 HTML 表單元素的其他標籤。 form 標籤本身的行為不同於它內部的元素。
    • Struts2 表單標籤包括下列標籤:
      • form textfield password radio checkbox checkboxlist select
      • doubleselect combobox optiontransferselect optgroup updownselect
      • textarea hidden file label reset submit token head
  52. 表單標籤
  53. 表單標籤的 name 和 value 屬性
    • 很多表單標籤( form 標籤除外)的 name 屬性和 value 屬性之間存在一個獨特的關係。 name 屬性除了為 HTML 表單元素指定名字,在表單提交時作為請求引數的名字外,同時它還對映到 Action 的屬性。
    • 在大多數情況下, name 屬性對映到一個簡單的 JavaBean 屬性,例如 name 屬性的值為” postalCode”, 在表單提交後, struts2 框架將會呼叫 Action 的 setPostalCode() 方法來設定屬性。
    • 有的時候你希望在表單元素中顯示 Action 屬性的資料,這時就輪到 value 屬性登場了,為 value 屬性指定表示式” %{postalCode}”, 這將會呼叫 Action 的 getPostalCode() 方法,並在表單中顯示返回的資料,之後, 使用者可以編輯這個值,然後重新提交它。
  54. form 標籤
    • form 標籤輸出一個 HTML 輸入表單,此外, xhtml 主題的 form 標籤還輸出表單元素外圍的表格。
    • 1) 通常情況下,當前輸出表單的請求和提交表單的請求屬於同一個名稱空間。例如:請求 /admin/updateCategory!default.action 輸出的表單,名稱空間會被假設為 /admin ,因此在使用 form 標籤時,可以不使用 namespace 屬性。如下:
      • <s:form action=“updateCategory” >
      • 如果輸出表單的請求和提交表單的請求分屬於不同的名稱空間,那麼可以通過
      • namespace 屬性指定處理表單提交的 action 所屬的名稱空間。
    • 2) 若通過 action 的一個非 execute 方法輸出表單,然後將表單提交給 action 預設的 execute 方法執行,那麼 form 標籤的 action 屬性可以忽略。例如:對於下面的表單:
      • <s:form >
      • <s:textfield name=“username” label=“ 使用者名稱” />
      • <s:submit />
      • </s:form>
      • 當訪問 /register!default.action 時, 輸出上表單, form 標籤會自動將 action 屬性設為
      • register ,這樣在表單提交後就會執行 action 的 execute 方法。
    • 3)method 和 enctype 是 HTML form 標籤的屬性。
    • 4) 當使用驗證框架時,將 form 標籤的 validate 屬性設為 true ,將自動生成客戶端的 JavaScript 驗證程式碼。
    • <s:form action=“register” method=“post” />
    • struts2 預設的主題是 xhtml, 上述程式碼在客戶端瀏覽器中的輸出如下:
    • <s:form id=“register” onsubmit=“return true” action=“register” method=“post”>
    • <table class=“wwFormTable”></table>
    • </s:form>
    • 可以看到 form 標籤內部輸出了一個 table 元素。
  55. textfield 標籤
    • textfield 標籤輸出一個 HTML 單行文字輸入控制元件,等價於 HTML 程式碼: <input type=“text” …/>
    • 看下面的程式碼:
      • <s:form action=“register” method=“post”>
      • <s:textfield name=“username” label=“ 使用者名稱” />
      • </s:form>
  56. password 標籤
    • password 標籤輸出一個 HTML 口令輸入控制元件,等價於 HTML 程式碼: <input type=“password” ../>
    • 例子: <s:password name=“password” label=“ 密碼” />
  57. textarea 標籤
    • textarea 標籤輸出一個 HTML 多行文字輸入控制元件,等價於 HTML 程式碼: <textarea …./>.
    • 例子:
    • <s:textarea name=“personal” cols=“30” rows=“5” label=“ 個人簡歷” />
  58. select 標籤
    • select 標籤輸出一個 HTML 列表框,等價於 HTML 程式碼:
    • <select …><option..></option></select>
  59. select 標籤示例
    • 示例一:
      • <s:form>
      • <s:select label=“ 最高學歷” name=“education” list=“{‘ 高中’,‘大學’,‘碩士’ }” />
      • </s:form>
      • 在 select 標籤的 list 屬性中直接使用 OGNL 表示式建立了一個列表,列表中的每一項都將作為 HTML 列表框的一個選項。
    • 示例二:
      • <s:form>
      • <s:select label=“ 最高學歷” name=“education” list=“#{1:‘ 高中’, 2:‘ 大學’, 3:‘ 碩士’ }” />
      • </s:form>
      • 在 select 標籤的 list 屬性中直接使用 OGNL 表示式建立了一個 Map 。在這裡要注意的是, Map 的 key 是作為列表框選項的值,而 Map 中的 value 是作為列表框選項的內容。
  60. select 標籤示例
    • 示例三:
      • <s:form>
      • <s:select label=“ 最高學歷” name=“education” list=“{‘ 高中’,‘大學’,‘碩士’ }” headerKey=“-1” headerValue=“ 請選擇你的學歷” />
      • Header 選項主要用來越提示作用,因此應該將 header 選項的值 ( 通過 headerKey 屬性設定 ) 設為無意義的值,例如此處的 -1.
    • 示例四:
      • <s:form>
      • <s:select label=“ 最高學歷” name=“education” list=“{‘ 高中’,‘大學’,‘碩士’ }” headerKey=“-1” headerValue=“ 請選擇你的學歷” emptyOption=“true” multiple=“true” / >
    • 使用 emptyOption 屬性在 header 選項後新增一個空的選項。
    • multiple 屬性設為 false ,則只能從下拉選單中選擇一個選項,如果設為 true ,則可以多選。
  61. optgroup 標籤
    • optgroup 標籤作為 select 標籤的子標籤使用,用於建立選項組。你可以在 select 標籤的標籤體中使用一個或者多個 optgroup 標籤,對選項進行邏輯分組。注意, optgroup 標籤本身不能巢狀。
    • 例子:
    • <%@ taglib prefix=“s” uri=“/struts-tags” %>
    • <s:form>
    • <s:select label= &quot; 選擇圖書 &quot; name= &quot;book&quot; list=&quot;#{1:'JAVA 核心程式設計 ',2:' 深入 struts2 學習 '}&quot; >
    • <s:optgroup label= &quot;C/C++ 圖書 &quot; list=&quot;#{3:'VC++ 程式設計詳解 ',4:'Spring 詳解 '}&quot;/>
    • <s:optgroup label= &quot;Oracle 圖書 &quot; list=&quot;#{5:'Oracle 基礎 ',6:'DBA 入門 '}&quot;/>
    • </s:select>
    • </s:form>
  62. optgroup 標籤注意
    • optgroup 標籤的 label 屬性指定選項組的組名。 optgroup 標籤對應的模板需要使用 listKey 和 listValue 屬性的值,因此你要麼為 list 屬性指定一個 Map 型別的值 ( 此時, listKey 預設為 Map.Entry 的 key , listValue 預設為 Map.Entry 的 value) ,要麼為 list 屬性指定一個物件列表,然後使用 listKey 和 listValue 屬性指定物件的屬性作為選項的值和內容。
  63. radio 標籤
    • radio 標籤輸出一組 HTML 單選按鈕,等價於一組 HTML 程式碼: <input type=“radio” …/>
    • 例子:
      • <%@ taglib prefix= &quot;s&quot; uri= &quot;/struts-tags&quot; %>
      • <s:form>
      • <s:radio name= &quot;user.sex&quot; value= &quot;1&quot; list=&quot;#{1 : ' 男 ', 0 : ' 女 '}&quot; label= &quot; 性別 &quot; />
      • </s:form>
  64. checkbox 標籤
    • checkbox 標籤輸出一個 HTML 核取方塊,等價於程式碼: <input type=“checkbox”…/>
    • checkbox 標籤建立一個 value 屬性為 true 或者為 false 的核取方塊。你可以通過 checkbox 標籤的 fieldValue 屬性來指定建立的 HTML 核取方塊 value 屬性的值。我們看下面的程式碼:
    • <s:checkbox name=“user.username” label=“ 是否顯示 Email” fieldValue=“true” />
    • 核取方塊的值是 true 還是 false ,是由 fieldValue 屬性來控制的,而不是由通常的 value 屬性來設定的。
    • 注意,除非你知道你要做什麼,否則不要將 fieldValue 屬性設定為 false 。將 fieldValue 屬性設定為 false 可能會導致一些問題。 HTML 規範規定,核取方塊只有在選中時才會被提交,在通常的 Servlet/JSP 處理過程中,我們可以通過判斷核取方塊的 name 屬性所指定的請求引數是否存在來獲知使用者是否選中了核取方塊,如果選中,則取出它的值。然而,在使用 struts2 框架時,這一切發生了一些微妙的變化。如果將 fieldValue 屬性設定為 false ,那麼核取方塊的值將是 false 。當沒有選中核取方塊時,提交的請求引數中不會有核取方塊對應的請求引數。不過,雖然 struts2 框架沒有接收到這個請求引數,但它仍然會將核取方塊對應的 action 屬性的值設為 false 。於是你就會看到一個奇怪的現象,那就是不管你是否選中核取方塊,對應的 action 屬性的值都是 false.
  65. checkboxlist 標籤
    • checkboxlist 標籤使用一個列表建立一系列核取方塊,屬性設定與 <s:select/> 和 <s:radio/> 類似,只是建立的是 HTML 核取方塊。不同的是, checkboxlist 標籤是多選標籤。
    • 示例:
      • <s:form>
      • <s:checkboxlist name= &quot;interest&quot; list= &quot;{' 足球 ',' 籃球 ',' 排球 ',' 游泳 '}&quot; label= &quot; 興趣愛好 &quot; />
      • </s:form>
  66. hidden 標籤
    • hidden 標籤輸出一個 HTML 隱藏表單元素,等價於 HTML 程式碼: <input type=“hidden”…/>. 在 xhtml 主題下, hidden 標籤與其它的標籤不太一樣, hidden 標籤並不輸出表行。 xhtml 主題直接從 simple 主題繼承了 hidden.ftl 模板。除了公共屬性外, hidden 標籤沒有特有的屬性。
    • 示例:
      • <s:hidden name=“id” value=“5” />
  67. submit 標籤
    • submit 標籤輸出一個提交按鈕。 submit 標籤和 form 標籤一起使用可以提供非同步表單提交功能。 submit 標籤可以輸出以下三種型別的提交按鈕。
      • input: 等價於 HTML 程式碼 <input type=“submit”…>
      • image: 等價於 HTML 程式碼 <input type=“image”…>
      • button: 等價於 HTML 程式碼 <input type=“submit”…>
    • HTML 的 button 標籤已經演進為可以分別指定提交的值 ( 通過 value 屬性指定 ) 和按鈕上顯示的文字 ( 通過標籤的內容來指定 ) ,但只能用於 IE6.0 以上版本的瀏覽器。
  68. submit 標籤示例
    • 例 1 :指定 image 型別的提交按鈕,使用 method 屬性。
      • <s:submit type=“image” method=“login” src=“images/login.gif” />
      • 上述程式碼在客戶端瀏覽器中的輸出如下:
      • <input type=“image” src=“images/login.gif” name=“method:login” value=“Submit”…./>
      • 注意生成的 input 元素的 name 屬性。
    • 例 2 :指定 button 型別的提交按鈕,使用 action 和 method 屬性。
      • <s:submit type=“button” action=“userManager” method=“login” label=“ 登入” />
      • 上述程式碼在客戶端瀏覽器中的輸出如下 :
      • <button type=“submit” name=“action:userManager!login” value=“submit” …/> 登入 </button>
      • 注意 button 標籤的 name 屬性。
      • 通過上面的例子可以看到 name 屬性有二個字首: method 和 action ,這是 struts2 提供的一種特性,即使用一些預定義的字首來命名一個按鈕,通過按鈕的名字來改變執行的行為。 Struts2 定義了 4 個字首,如下:
      • method-------method:login
      • action--------action:userManager
      • redirect------redirect:cancel.jsp
      • redirection-action------redirect-action:register
  69. method 字首
    • 使用 method 字首,來取代 action 預設的 execute() 方法的執行。例如一個表單同時用於使用者註冊和登入,那麼可以編寫程式碼如下:
    • <s:form action=“userManager”>
      • <s:textfield label=“ 使用者名稱” name=“user.username” />
      • <s:password label=“ 密碼” name=“user.password” />
      • <s:submit value=“ 登入” name=“method:login” />
      • <s:submit value=“ 註冊” name=“method:reg” />
      • </s:form>
      • 注意: 1) 對於 input 型別的提交按鈕,不能通過 submit 標籤的 label 屬性來設定提交按鈕上的文字,只能使用 value 屬性。
      • 2) 可以在 submit 標籤的 name 屬性中直接使用 method 字首,也可以像前面給出的例子中使用 submit 標籤的 method 屬性來指定處理請求的 action 方法。
  70. action 字首
    • 使用 action 字首,取代 form 標籤指定的 action ,將請求導向到另外的 action 進行處理。
    • 示例:
    • <s:form action=“login”>
      • <s:textfield label=“ 使用者名稱” name=“user.username” />
      • <s:password label=“ 密碼” name=“user.password” />
      • <s:submit value=“ 登入” />
      • <s:submit value=“ 註冊” name=“action:register” />
      • </form>
    • 如果使用者已經註冊,可以直接登入,否則單擊註冊按鈕,轉到註冊頁面。 action 字首也可以和 struts2 的動態方法呼叫結合使用,例如: name=“action:userManager!register”.
  71. redirect 字首
    • 使用 redirect 字首將請求重定向到其他的 URL ,甚至可以是 Web 應用程式外部的 URL 。
    • 示例:
    • <s:form action=“login”>
      • <s:textfield label=“ 使用者名稱” name=“user.username” />
      • <s:password label=“ 密碼” name=“user.password” />
      • <s:submit value=“ 登入” />
      • <s:submit value=“ 註冊” name=“redirect:www.163.com” />
      • </form>
  72. redirect-action 字首
    • 使用 redirect-action 字首將請求重定向到其他的 action 。在內部, struts2 使用 ServletRedirectResult 來執行這個任務。
    • 示例:
    • <s:form action=“login”>
      • <s:textfield label=“ 使用者名稱” name=“user.username” />
      • <s:password label=“ 密碼” name=“user.password” />
      • <s:submit value=“ 登入” />
      • <s:submit value=“ 註冊” name=“redirect-action : register” />
      • </form>
  73. reset 標籤
    • reset 標籤輸出一個重置按鈕。 reset 標籤與 form 標籤一起使用,用來提供表單的重置。 reset 標籤可以輸出以下兩種型別的重置按鈕:
      • input: 等價於 HTML 程式碼 <input type=“reset”…>
      • button: 等價於 HTML 程式碼 <button type=“reset”…>
    • 示例
    • <s:reset value=“ 重置” />
    • <s:reset type=“button” label=“ 重置” />
    • 如果是型別為 input 的重置按鈕,則只能通過 value 屬性來設定重置按鈕上的文字。
  74. label 標籤
    • Xhtml 主題下的 label 標籤輸出兩個 HTML 的 label 標籤 (simple 主題下的 label 標籤只輸出一人 HTML label 標籤 ) ,分別位於一行的兩列,左邊的 label 標籤起提示作用,右列的 label 標籤用於顯示只讀的 action 屬性資料。
    • 示例
      • <s:label label=“ 使用者名稱” name=“user.username” />
      • 如果 Action 例項已經建立,並且 user.username 有值,那麼在錶行的右列中將顯示 user.username 的值。
  75. token 標籤與 file 標籤
    • token 標籤輸出兩個隱藏的表單欄位,用於防止表單的重複提交。要讓 token 標籤正常工作,需要啟用 TokenInterceptor 或者 TokenSessionInterceptor 攔截器。
    • 示例: <s:token /> 具體使用後面章節講解。
    • file 標籤輸出一個 HTML 檔案選擇框,等價於 HTML 程式碼: <input type=“file” …/>.
    • 示例:
      • <s:file name=“uploadFile” accept=“text / *” />
      • <s:file name=“anotherUploadFile” accept=“text/html,text/plain” />
      • 檔案上傳後面章節詳解。
  76. 非表單標籤
    • Struts2 的非表單標籤包括下列標籤:
      • component 、 a 、 actionerror 、 actionmessage 、 fielderror
    • component 標籤使用特定的模板輸出一個自定義的 UI 小部件 (widget) 。
    • a 標籤建立一個 HTML 超連結,等價於 HTML 程式碼: <a href=“….” />.
    • a 標籤雖然可以在 simple 、 xhtml 和其它主題中使用,但它實際上是為了更好地和 ajax 主題一起工作佈置而設計的 .
    • a 標籤有一個 String 型別的 href 屬性,用於指定連結的 URL 。看下面的例子:
      • <s:a href=“register!default.action”> 重新註冊 </s:a>
  77. actionerror 、 actionmessage 、 fielderror 標籤
    • actionerror 、 actionmessage 、 fielderror 標籤都是用於輸出訊息的 .
    • 不同的是 :
      • actionerror 標籤輸出 action 的錯誤訊息,
      • actionmessage 標籤輸出 action 的一般訊息,
      • fielderror 標籤輸出 action 欄位的錯誤訊息 .
    • actionerror 標籤輸出 action 的 actionErrors 屬性 (property) 儲存的錯誤訊息, actionErrors 是一個 Collection 型別的屬性;
    • actionmessage 標籤輸出 action 的 actionMessages 屬性儲存的訊息, actionMessages 是一個 Collection 型別的屬性;
    • fielderror 標籤輸出 action 的 fieldErrors 屬性儲存的欄位錯誤訊息, actionMessages 是一個 Map 型別的屬性;
    • 對於 fielderror 標籤,可以通過巢狀的 param 標籤來指定輸出特定欄位的錯誤訊息。
    • actionerror 、 actionmessage 、 fielderror 標籤輸出訊息的佈局依賴於使用的主題。
  78. 示例 : MessageAction .java
    • public class MessageAction extends ActionSupport
    • {
    • @Override
    • public String execute() throws Exception
    • {
    • // 新增 action 錯誤訊息
    • addActionError(&quot;Action Error Message1&quot;);
    • addActionError(&quot;Action Error Message2&quot;);
    • // 新增 action 一般性訊息
    • addActionMessage(&quot;Action Message1&quot;);
    • addActionMessage(&quot;Action Message2&quot;);
    • // 新增欄位訊息
    • addFieldError(&quot;field1&quot;,&quot;field1 error&quot;);
    • addFieldError(&quot;field2&quot;,&quot;field2 error&quot;);
    • return SUCCESS ;
    • }
    • }
  79. 示例 : message.jsp
    • <%@ page contentType= &quot;text/html;charset=GBK&quot; %>
    • <%@ taglib prefix= &quot;s&quot; uri= &quot;/struts-tags&quot; %>
    • <h3> 輸出 action 的錯誤訊息 </h3>
    • <s:actionerror/>
    • <h3> 輸出 action 的一般性訊息 </h3>
    • <s:actionmessage/>
    • <h3> 輸出所有欄位的錯誤訊息 </h3>
    • <s:fielderror/>
    • <h3> 輸出特定欄位的錯誤訊息 </h3>
    • <s:fielderror>
    • <s:param value= &quot;'field2'&quot; />
    • </s:fielderror>

相關文章