3.3 Struts2標籤庫應用

        Struts2 把全部標籤都定義在URI/struts-tags的命名空間下。能夠分爲3類:UI標籤(主要用於生成HTML元素的標籤,可分爲表單標籤和非表單標籤)、非UI標籤(主要用於數據訪問和邏輯控制等,分爲數據標籤和控制標籤)和Ajax標籤(主要用於Ajax支持的標籤)。html

3.3.1 Struts 2的OGNL表達式

1.OGNL表達式

    OGNL(Object Graphic Navigation Language對象圖導航語言),是個開源項目。OGNL是一種功能強大的EL(Expression Language,表達式語言),能夠通過簡單的表達式來訪問Java對象中的屬性java

    OGNL首先在WebWork項目中獲得應用,OGNL是Struts2框架視圖默認的表達式語言,OGNL表達式是Struts 2框架的特色之一node

    標準的OGNL會設定一個根對象(root對象)。假設使用標準OGNL表達式來求值(不是Struts 2 OGNL),若是OGNL上下文有兩個對象,foo對象和bar對象,同時foo對象被設置爲根對象(root),則利用下面的OGNL表達式求值。web

#foo.blah // 返回foo.getBlah()
#bar.blah // 返回bar.getBlah()
blah // 返回foo.getBlah(),由於foo爲根對象

    若是要訪問的不是根對象須要使用命名空間,用「#」表示。若是是根對象,則不用指定
ajax

    在Struts 2框架中值棧(Value Stack)就是OGNL的根對象。假設值棧中存在兩個對象實例Man和Animal,這兩個對象實例都有一個name屬性,Animal有一個species屬性,Man有一個salary屬性。假設Animal在值棧的頂部,Man在Animal後面,如圖所示。session

一個包含了Animal和Man的值棧app

 

下面的代碼片斷能更好地理解OGNL表達式。框架

species // 調用animal.getSpecies()
salary // 調用man.getSalary()
name // 調用animal.getName(),由於Animal位於值棧的頂部

    最後一行實例代碼返回的是animal.getName()返回值,即返回了Animal的name屬性,由於Animal是值棧的頂部元素,OGNL將從頂部元素搜索,因此會返回Animal的name屬性值。若是要得到Man的name值,則須要以下代碼:
jsp

man.name

    Struts 2容許在值棧中使用索引,實例代碼以下:post

[0].name // 調用animal.getName()
[1].name // 調用man.getName()

    Struts 2中的OGNL Context是ActionContext,如圖所示。

 

Struts 2的OGNL Context結構示意圖

 

    因爲值棧是Struts 2中OGNL的根對象。若是用戶須要訪問值棧中的對象,則能夠經過以下代碼訪問值棧中的屬性:

${foo} // 得到值棧中的foo屬性

若是訪問其餘Context中的對象因爲不是根對象,在訪問時須要加#前綴

  • application對象:用來訪問ServletContext,如#application.userName或者#application  ["userName"],至關於調用Servlet的getAttribute("userName")。  

  • session對象:用來訪問HttpSession,如#session.userName或者#session["userName"],至關於調用session.getAttribute("userName")。  

  • request對象:用來訪問HttpServletRequest屬性的Map,如#request.userName或者#request["userName"],至關於調用request.getAttribute("userName")。如在3.2.1節中StrutsAction類中代碼:

Map request=(Map)ActionContext.getContext().get("request");
request.put("name",getName());

    這就是先獲得request對象,而後把值放進去,在該例的success.jsp中有:

<s:property value="#request.name"/>

    其中#request.name至關於調用了request.getAttribute("name")。

2.OGNL集合操做

    使用以下代碼直接生成一個List對象

{e1, e2, e3…}

    下面的代碼能夠直接生成一個Map對象

#{key: value1, key2: value2, …}

    對於集合類型,OGNL表達式可使用innot in兩個元素符號。其中,in表達式用來判斷某個元素是否在指定的集合對象中;not in判斷某個元素是否不在指定的集合對象中,代碼以下所示:

<s: if test="'foo' in {'foo', 'bar'}">
…
</s: if>


<s: if test="'foo' not in {'foo', 'bar'}">
…
</s: if>

    除了in和not in以外,OGNL還容許使用某個規則得到集合對象的子集,經常使用的有如下3個相關操做符。 

  • ?:得到全部符合邏輯的元素。  

  • ^:得到符合邏輯的第一個元素  

  • $:得到符合邏輯的最後一個元素。

以下面的代碼:

Person.relatives.{?# this.gender=='male'}

    該代碼能夠得到Person的全部性別爲male的relatives集合

3.3.2 數據標籤

    數據標籤屬於非UI標籤,主要用於提供各類數據訪問相關的功能,數據標籤主要包括如下幾個。

  • property:用於輸出某個值。  

  • set:用於設置一個新變量。  

  • param:用於設置參數,一般用於bean標籤和action標籤的子標籤。  

  • bean:用於建立一個JavaBean實例。  

  • action:用於在JSP頁面直接調用一個Action。    

  • date:用於格式化輸出一個日期。  

  • debug:用於在頁面上生成一個調試連接,當單擊該連接時,能夠看到當前值棧和Stack  Context中的內容  

  • il8n:用於指定國際化資源文件的baseName。  

  • include:用於在JSP頁面中包含其餘的JSP或Servlet資源。  

  • push:用於將某個值放入值棧的棧頂。  

  • text:用於輸出國際化(國際化內容會在後面講解)。  

  • url:用於生成一個URL地址。

1. s:property 標籤

    property標籤的做用是輸出指定值。property標籤輸出value屬性指定的值。若是沒有指定的value屬性,則默認輸出值棧棧頂的值。該標籤有以下幾個屬性:

  • default:該屬性是可選的,若是須要輸出的屬性值爲null,則顯示default屬性指定的值 

  • escape:該屬性是可選的,指定是否escape  HTML代碼。  

  • value:該屬性是可選的,指定須要輸出的屬性值,若是沒有指定該屬性,則默認輸出值棧棧頂的值。該屬性也是最經常使用的,如前面用到的:

<s:property value="#request.name"/>
  •  id:該屬性是可選的,指定該元素的標誌

2. s:set 標籤

    對值棧中的表達式進行求值,並將結果賦給特定做用域中的某個變量名該標籤有以下幾個屬性: 

  • name:該屬性是必選的,從新生成新變量的名字  

  • scope:該屬性是可選的,指定新變量的存放範圍。通常爲application、session、request、page和action。若是沒有指定該屬性,則默認放置在值棧中  

  • value:該屬性是可選的,指定賦給新變量的值。若是沒有指定該屬性,則將值棧棧頂的值賦給新變量  

  • id:該屬性是可選的,指定該元素的引用id。

    下面是一個簡單例子,展現了property標籤訪問存儲於session中的user對象的多個字段:

<s:property value="#session['user'].username"/>
<s:property value="#session['user'].age"/>
<s:property value="#session['user'].address"/>

    因爲每次都要重複使用#session['user'],不只煩人還容易引起錯誤,更好的作法是定義一個臨時變量,使用set標籤使得代碼易於閱讀:

<s:set name="user" value="#session['user'] " />
<s:property value="#user.username"/>
<s:property value="#user.age" />
<s:property value="#user.address" />

3. s:param 標籤

    param標籤主要用於爲其餘標籤提供參數,該標籤有以下幾個屬性:

  • name:該屬性是可選的,指定須要設置參數的參數名。  

  • value:該屬性是可選的,指定須要設置參數的參數值。  

  • id:該屬性是可選的,指定引用該元素的id。

例如,要爲name爲fruit的參數賦值:

<s:param name= "fruit">apple</s:param>

或者

<s:param name="fruit" value="apple" />

    指定一個名爲fruit的參數,該參數的值爲apple對象的值若是該對象不存在,則fruit的值爲null

    若是想指定fruit參數的值爲apple字符串,則應該這樣寫:

<s:param name="fruit" value="'apple'" />

4. s:bean 標籤

    用於建立一個JavaBean實例。建立JavaBean實例時,能夠在該標籤內使用param標籤爲該JavaBean實例傳入屬性。若是要使用param標籤傳入屬性值,則應該爲該JavaBean類提供setter方法。若是還但願訪問該屬性值,則必須爲該屬性提供getter方法。該標籤有以下幾個屬性:

  • name:該屬性是必選的,用來指定要實例化的JavaBean的實現類。  

  • id:該屬性是可選的,若是指定了該屬性,則該JavaBean實例會被放入Stack Context中,從而容許直接經過id屬性來訪問該JavaBean實例。下面是一個簡單的例子:

    有一個Student類,該類中有name屬性,並有其getter和setter方法:

public class Student {
    private String name;
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name=name;
    }
}

    而後在JSP文件的body體中加入下面的代碼:

<s:bean name="Student">
    <s:param name="name" value="'zhangsan'"/>
    <s:property value="name"/>
</s:bean>

    在項目中導入Struts 2的Jar包,再把Student類放在項目的src文件夾下(若是Student類在在某個包下面,那麼<s:bean>標籤的name要加上包名。例如org.bean.Student),<s:bean>標籤內容放在一個JSP文件的body體內,再修改web.xml文件,就能夠部署運行該項目,會獲得如圖所示的界面。

bean標籤實例界面

    也能夠把bean標籤的內容改成:

<s:bean name="Student" id="s" >
    <s:param name="name" value="'zhangsan'"/>
</s:bean>
<s:property value="#s.name"/>

5. s:action 標籤

    使用action標籤能夠容許在JSP頁面中直接調用Action。該標籤有如下幾個屬性:

  • id:該屬性是可選的,該屬性將會做爲該Action的引用標誌id。  

  • name:該屬性是必選的,指定該標籤調用哪一個Action。  

  • namespace:該屬性是可選的,指定該標籤調用的Action所在的namespace。  

  • executeResult:該屬性是可選的,指定是否要將Action的處理結果頁面包含到本頁面。若是值爲true,就是包含,false就是不包含,默認爲false  

  • ignoreContextParam:該屬性是可選的,指定該頁面中的請求參數是否須要傳入調用的Action。若是值爲false,將本頁面的請求參數傳入被調用的Action。如爲true,不將本頁面的請求參數傳入到被調用的Action。

6. s:date 標籤

    date標籤主要用於格式化輸出一個日期。該標籤有以下屬性:

  • format:該屬性是可選的,若是指定了該屬性,將根據該屬性指定的格式來格式化日期。  

  • nice:該屬性是可選的,該屬性的取值只能是true或false,用於指定是否輸出指定日期和當前時刻之間的時差默認爲false,即不輸出時差。  

  • name:屬性是必選的指定要格式化的日期值  

  • id:屬性是可選的,指定引用該元素的id值。

    nice屬性爲true時,通常不指定format屬性。由於nice爲true時,會輸出當前時刻與指定日期的時差,不會輸出指定日期。當沒有指定format,也沒有指定nice="true"時,系統會到國際化資源文件中尋找key爲struts.date.format的消息將該消息當成格式化文原本格式化指定日期若是沒法找到,則默認採用DateFormat.MEDIUM格式輸出。其用法爲:

<s:date name="指定日期取值" format="日期格式"/><!-- 按指定日期格式輸出 -->
<s:date name="指定日期取值" nice="true"/><!-- 輸出時間差 -->
<s:date name="指定日期取值"/><!—默認格式輸出-->

例子:

java

import java.util.Date;
public class Student {
    private Date birthday;
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

jsp

  1.     <s:bean name="Student">
            <s:param name="birthday" value="'2011-12-10'"/>
            <s:date name="birthday" /><br/>
            <s:date name="birthday" format="yyyy-MM-dd hh:mm:ss"/><br/>
            <s:date name="birthday" nice="true"/><br/>
        </s:bean>


7. s:include 標籤

    include標籤用於將一個JSP頁面或一個Servlet包含到本頁面中。該標籤有以下屬性: 

  • value:該屬性是必選的,指定須要被包含的JSP頁面或Servlet。  

  • id:該屬性是可選的,指定該標籤的id引用。

用法以下:

<s:include value="JSP或Servlet文件" id="自定義名稱"/>


3.3.3 控制標籤

    屬於非UI標籤,主要用於完成流程的控制,以及對值棧的控制。控制標籤有如下幾個:

  • if:用於控制選擇輸出的標籤。  

  • elseif:用於控制選擇輸出的標籤,必須和if標籤結合使用。  

  • else:用戶控制選擇輸出的標籤,必須和if標籤結合使用。  

  • append:用於將多個集合拼接成一個新的集合。  

  • generator:用於將一個字符串按指定的分隔符分隔成多個字符串,臨時生成的多個子字符串可使用iterator標籤來迭代輸出  

  • iterator:用於將集合迭代輸出。  

  • merge:用於將多個集合拼接成一個新的集合,但與append的拼接方式不一樣。  

  • sort:用於對集合進行排序。  

  • subset:用於截取集合的部分元素,造成新的子集合。

1. s:if, s:elseif, s:else標籤

    這3個標籤能夠組合使用,但只有if標籤能夠單獨使用,而elseif和else標籤必須與if標籤結合使用。if標籤能夠與多個elseif標籤結合使用,但只能與一個else標籤使用。其用法格式以下:

<s:if test="表達式">
標籤體
</s:if>
<s:elseif test="表達式">
標籤體
</s:elseif>
<!--容許出現屢次elseif標籤-->
...
<s:else>
標籤體
</s:else>

2. s:iterator 標籤

    該標籤主要用於對集合進行迭代,這裏的集合包含List、Set,也能夠對Map類型的對象進行迭代輸出。該標籤的屬性以下: 

  • value:該屬性是可選的,指定被迭代的集合,被迭代的集合一般都由OGNL表達式指定。若是沒有指定該屬性,則使用值棧棧頂的集合  

  • id:該屬性是可選的,指定集合元素的id。  

  • status:該屬性是可選的,指定迭代時的IteratorStatus實例,經過該實例可判斷當前迭代元素的屬性。若是指定該屬性,其實例包含以下幾個方法:   

    • int getCount():返回當前迭代了幾個元素    

    • int getIndex():返回當前被迭代元素的索引。    

    • boolean isEven:返回當前被迭代元素的索引元素是不是偶數    

    • boolean isOdd:返回當前被迭代元素的索引元素是否是奇數。    

    • boolean isFirst:返回當前被迭代元素是不是第一個元素。    

    • boolean isLast:返回當前被迭代元素是不是最後一個元素。

應用舉例:

<%@ page language="java" pageEncoding="utf-8"%>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
    <head>
        <title>控制標籤</title>
    </head>
    <body>
        <table border="1" width="200">
            <s:iterator value="{'apple','orange','pear','banana'}"id="fruit" status="st">
                <tr <s:if test="#st.even">style="background-color:silver"</s:if>>
                    <td><s:property value="fruit"/></td>
                </tr>
            </s:iterator>
        </table>
    </body>
</html>

    經過添加Struts 2必須的Jar包,再創建上面JSP文件,修改web.xml後,就能夠部署運行,運行結果如圖所示。

iterator標籤實例運行結果

 

3. s:append 標籤

    用於將多個集合對象拼接起來,組成一個新的集合。必須指定一個id屬性,該屬性肯定拼接的新集合的名稱。該標籤經過param標籤來指定每個集合,而後把這些集合拼接起來。

    應用舉例,能夠把上例的JSP文件進行修改,其代碼爲:

<%@ page language="java" pageEncoding="utf-8"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<html>
    <head>
        <title>控制標籤</title>
    </head>
    <body>
        <s:append id="newList">
            <s:param value="{'apple','orange','pear','banana'}"></s:param>
            <s:param value="{'chinese','english','french'}"></s:param>
        </s:append>
        <table border="1" width="200">
            <s:iterator value="#newList" id="fruit" status="st">
                <tr <s:if test="#st.even">style="background-color:silver"</s:if>>
                    <td>
                        <s:property value="fruit" />
                    </td>
                </tr>
            </s:iterator>
        </table>
    </body>
</html>

    部署運行,運行結果如圖所示。

append標籤實例運行界面

4.  s:merge 標籤

    與append標籤的區別,只是拼接方式不一樣

    假設有2個集合,第一個集合包含3個元素,第二個集合包含2個元素,分別用append標籤和merge標籤方式進行拼接,它們產生新集合的方式有所區別。下面分別列出:

用append方式拼接,新集合元素順序爲: 

  • 第1個集合中的第1個元素  

  • 第1個集合中的第2個元素  

  • 第1個集合中的第3個元素  

  • 第2個集合中的第1個元素  

  • 第2個集合中的第2個元素

用merge方式拼接,新集合元素順序爲: 

  • 第1個集合中的第1個元素  

  • 第2個集合中的第1個元素  

  • 第1個集合中的第2個元素  

  • 第2個集合中的第2個元素  

  • 第1個集合中的第3個元素

代碼以下:

<%@ page language="java" pageEncoding="utf-8"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<html>
    <head>
        <title>控制標籤</title>
    </head>
    <body>
        <s:merge id="newList2">
            <s:param value="{'apple','orange','pear','banana'}"></s:param>
            <s:param value="{'chinese','english','french'}"></s:param>
        </s:merge>
        <table border="1" width="200">
            <s:iterator value="#newList2" id="fruit2" status="st2">
                <tr <s:if test="#st2.even">style="background-color:silver"</s:if>>
                    <td>
                        <s:property value="fruit2" />
                    </td>
                </tr>
            </s:iterator>
        </table>
    </body>
</html>

3.3.4 表單標籤

    大部分的表單標籤和HTML表單元素是一一對應的關係,以下面的代碼片斷:

<s:form action="login.action" method="post"/>

對應着:

<form action="login.action" method="post"/>


<s:textfield name="username" label="用戶名" />

對應着:

用戶名:<input type="text" name="username">


<s:password name="password" label="密碼"/>

對應着:

密碼:<input type="password" name="pwd">

     還有下面這種狀況,若是有這樣一個JavaBean類,類名爲「User」,該類中有兩個屬性:一個是username;另外一個是password,並分別生成它們的getter和setter方法,在JSP頁面的表單中能夠這樣爲表單元素命名:

<s:textfield name="user.username" label="用戶名" />
<s:password name="user.password" label="密碼"/>

下面介紹和HTML標籤元素不是一一對應的幾個重要的表單標籤:

1. s:checkboxlist 標籤

    建立多個複選框。該標籤須要指定一個list屬性。用法舉例:

<s:checkboxlist label="請選擇你喜歡的水果" list="{'apple','oranger','pear','banana'}" name="fruit">
</s:checkboxlist>

    或者爲:

<s:checkboxlist label="請選擇你喜歡的水果" list="#{1:'apple',2:'oranger',3:'pear',4:'banana'}" name="fruit">
</s:checkboxlist>

這兩種方式的區別:前一種根據name取值時取的是選中字符串的值;後一種在頁面上顯示的是value的值,而根據name取值時取的倒是對應的key,這裏就是一、二、3或4。

 

2. s:combobox 標籤

    combobox標籤生成一個單行文本框和下拉列表框的組合。兩個表單元素只能對應一個請求參數,只有單行文本框裏的值才包含請求參數,下拉列表框只是用於輔助輸入,並無name屬性,故不會產生請求參數。用法舉例:

<s:combobox label="請選擇你喜歡的水果" list="{'apple','oranger','pear','banana'}" name="fruit">
</s:combobox>

3. s:datetimepicker 標籤

    datetimepicker標籤用於生成一個日期、時間下拉列表框。當使用該日期、時間列表框選擇某個日期、時間時,系統會自動將選中日期、時間輸出指定文本框中。用法舉例:

<s:form action="" method="">
    <s:datetimepicker name="date" label="請選擇日期"></s:datetimepicker>
</s:form>

    注意:在使用該標籤時,要在HTML的head部分加入<s:head/>

 

4. s:select 標籤

    select標籤用於生成一個下拉列表框,經過爲該元素指定list屬性的值,來生成下拉列表框的選項。用法舉例:

<s:select list="{'apple','oranger','pear','banana'}"  label="請選擇你喜歡的水果"></s:select>

或者爲:

<s:select list="fruit" list="#{1:'apple',2:'oranger',3:'pear',4:'banana'}"  listKey="key"listValue="value"></s:select>

 

5. s:radio 標籤

    radio標籤的用法與checkboxlist用法很類似,惟一的區別就是checkboxlist生成的是複選框,而radio生成的是單選框。用法舉例:

<s:radio label="性別" list="{'男','女'}" name="sex"></s:radio>

或者爲:

<s:radio label="性別" list="#{1:'男',0:'女'}" name="sex">
</s:radio>

 

6. s:head 標籤

    head標籤主要用於生成HTML頁面的head部分。在介紹<s:datetimepicker>標籤時說過,要在head中加入該標籤,主要緣由是<s:datetimepicker>標籤中有一個日曆小控件,其中包含了JavaScript代碼,因此要在head部分加入該標籤。

    若是須要在頁面中使用Ajax組件,就須要在head標籤中加入theme="ajax"屬性

3.3.5 非表單標籤

    非表單標籤主要用於在頁面中生成一些非表單的可視化元素。這些標籤不常常用到,下面大體介紹一下這些標籤:

  • a:生成超連接。

  • actionerror:輸出Action實例的getActionMessage()方法返回的消息。

  • component:生成一個自定義組件。

  • div:生成一個div片斷。

  • fielderror:輸出表單域的類型轉換錯誤、校驗錯誤提示。  

  • tablePanel:生成HTML頁面的Tab頁。

  • tree:生成一個樹形結構。

  • treenode:生成樹形結構的節點。

 

附:目錄《JavaEE基礎實用教程》筆記說明

相關文章
相關標籤/搜索