form 標(biāo)簽的列表是 Struts UI 標(biāo)簽的子集。這些標(biāo)簽幫助呈現(xiàn) Struts web 應(yīng)用程序必需的用戶接口,并且能夠被劃分為三種類別。本章將會(huì)帶你瀏覽 UI 標(biāo)簽的這三種類別。
我們已經(jīng)在我們的示例中使用過這些標(biāo)簽了,在本章中我們將一帶而過。讓我們看看帶有幾個(gè)簡單的 UI 標(biāo)簽的簡單的視圖頁面 email.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <s:head/> <title>Hello World</title> </head> <body> <s:div>Email Form</s:div> <s:text name="Please fill in the form below:" /> <s:form action="hello" method="post" enctype="multipart/form-data"> <s:hidden name="secret" value="abracadabra"/> <s:textfield key="email.from" name="from" /> <s:password key="email.password" name="password" /> <s:textfield key="email.to" name="to" /> <s:textfield key="email.subject" name="subject" /> <s:textarea key="email.body" name="email.body" /> <s:label for="attachment" value="Attachment"/> <s:file name="attachment" accept="text/html,text/plain" /> <s:token /> <s:submit key="submit" /> </s:form> </body> </html>
如果你了解 HTML,那么所有的標(biāo)簽都是非常普通的 HTML 標(biāo)簽,只不過在每個(gè)標(biāo)簽和不同的屬性中帶有一個(gè)額外的前綴 s:。當(dāng)我們執(zhí)行上述程序時(shí),我們會(huì)得到如下所示的用戶接口,前提是你已經(jīng)為所有用到的鍵設(shè)置了合適的映射。
http://wiki.jikexueyuan.com/project/struts-2/images/simpleuitag.jpg" alt="" />
正如顯示的一樣,s:head 生成了 Struts2應(yīng)用程序必需的 javascript 和 stylesheet。
接下來,我們有 s:div 和 s:text 元素。s:div 元素用于呈現(xiàn) HTML Div 元素。這對(duì)不想把 HTML 和 Struts 標(biāo)簽混合到一起的用戶來說是非常有用的。對(duì)于這些人,他們必須選擇使用 s:div 元素來呈現(xiàn) div。
s:text 元素用于在屏幕上呈現(xiàn)一個(gè)文本。
接下來,我們有類似的 s:form 標(biāo)簽。s:form 標(biāo)簽有一個(gè)操作屬性,決定了表單提交的位置。因?yàn)樵诒韱沃杏幸粋€(gè)文件上傳元素,我們必須把 enctype 設(shè)置為 multipart。否則,我們可以離開這個(gè)空白。
在表單標(biāo)簽的結(jié)尾,我們有 s:submit 標(biāo)簽。這是用于提交表單的。當(dāng)表單被提交時(shí),所有的表單的值都會(huì)提交給 s:form 標(biāo)簽中指定的操作。
在 s:form 標(biāo)簽內(nèi)部,有一個(gè)隱藏的屬性稱為 secret。這會(huì)呈現(xiàn)在 HTML 中隱藏的元素。在我們的例子中, "secret" 元素有 "abracadabra" 值。這個(gè)元素對(duì)終端用戶是不可見的且它用于將狀態(tài)從一個(gè)視圖傳遞給另一個(gè)視圖。
接下來,我們有 s:label,s:textfield,s:password 和 s:textarea 標(biāo)簽。這是分別用于呈現(xiàn)標(biāo)記、輸入字段、密碼和文本域的。我們已經(jīng)在 "Struts - Sending Email" 例子中的操作中了解了這些標(biāo)簽的使用方法。在這里需要注意的很重要的一點(diǎn)是 "key" 屬性的使用。"key" 屬性是用于從屬性文件中為這些控制提取標(biāo)記的。在 Struts2 本地化,國際化章節(jié)中,我們已經(jīng)介紹了這個(gè)特征。
然后,我們有 s:file 標(biāo)簽,用于呈現(xiàn)輸入文件上傳組件。這個(gè)組件允許用戶上傳文件。在這個(gè)例子中,我們使用的是 s:file 標(biāo)簽的 "accept" 屬性來指定哪個(gè)文件類型是允許上傳的。
最后我們有 s:token 標(biāo)簽。 token 標(biāo)簽生成了一個(gè)唯一的 token,用于確認(rèn)一個(gè)表單是否被提交了兩次。
當(dāng)呈現(xiàn)表單時(shí),一個(gè)隱藏的變量就會(huì)被替換成 token 值。比如,token 是 "ABC"。當(dāng)表單被提交時(shí),Struts 過濾器檢查與會(huì)話中存儲(chǔ)的 token 不一致的 token。如果相匹配的話,它會(huì)把這個(gè) token 從會(huì)話中移除出去?,F(xiàn)在,如果表單被意外的重復(fù)提交了(或通過刷新或點(diǎn)擊了瀏覽器的后退按鈕),表單就會(huì)被重提交,其中 token 為 "ABC"。在這種情況下,過濾器會(huì)再次檢查會(huì)話中與這個(gè) token 不一致的 token。但是由于 token "ABC" 已經(jīng)從從會(huì)話中被刪除了,它不會(huì)再次匹配,Struts 過濾器就會(huì)拒絕這個(gè)請(qǐng)求。
組 UI 標(biāo)簽是用于創(chuàng)建單選按鈕和復(fù)選框的。讓我們看一個(gè)帶有復(fù)選框和單選按鈕標(biāo)簽的簡單的視圖頁面 HelloWorld.jsp:
<%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <html> <head> <title>Hello World</title> <s:head /> </head> <body> <s:form action="hello.action"> <s:radio label="Gender" name="gender" list="{'male','female'}" /> <s:checkboxlist label="Hobbies" name="hobbies" list="{'sports','tv','shopping'}" /> </s:form> </body> </html>
當(dāng)我們執(zhí)行上述程序時(shí),會(huì)得到類似如下所示的輸出:
http://wiki.jikexueyuan.com/project/struts-2/images/sturtsgrouptag.jpg" alt="" />
現(xiàn)在讓我們看看這個(gè)例子。在第一個(gè)例子中,我們創(chuàng)建的是一個(gè)簡單的帶有標(biāo)記 "Gender" 的單選按鈕。單選按鈕的名字屬性是強(qiáng)制性的,所以我們指定了名字為 "Gender"。然后我們給這個(gè) gender 提供了一個(gè)列表。列表用值 "male" 和 "female" 填充。因此,在輸出中,我們得到了帶有兩個(gè)值的單選按鈕。
在第二個(gè)例子中,我們創(chuàng)建的是復(fù)選框列表。這是用來收集用戶愛好的。用戶可能有多個(gè)愛好,因此我們使用的是復(fù)選框而不是單選按鈕。復(fù)選框用列表 "sports","Tv" 和 "Shopping" 填充。這把愛好以復(fù)選框列表的形式展現(xiàn)出來。
讓我們展示 Struts 提供的選擇標(biāo)簽的不同的變量。請(qǐng)看如下所示的帶有選擇標(biāo)簽的簡單的視圖頁面 HelloWorld.jsp:
<%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <html> <head> <title>Hello World</title> <s:head /> </head> <body> <s:form action="login.action"> <s:select name="username" label="Username" list="{'Mike','John','Smith'}" /> <s:select label="Company Office" name="mySelection" value="%{'America'}" list="%{#{'America':'America'}}"> <s:optgroup label="Asia" list="%{#{'India':'India','China':'China'}}" /> <s:optgroup label="Europe" list="%{#{'UK':'UK','Sweden':'Sweden','Italy':'Italy'}}" /> </s:select> <s:combobox label="My Sign" name="mySign" list="#{'aries':'aries','capricorn':'capricorn'}" headerKey="-1" headerValue="--- Please Select ---" emptyOption="true" value="capricorn" /> <s:doubleselect label="Occupation" name="occupation" list="{'Technical','Other'}" doubleName="occupations2" doubleList="top == 'Technical' ? {'I.T', 'Hardware'} : {'Accounting', 'H.R'}" /> </s:form> </body> </html>
當(dāng)我們執(zhí)行上述程序時(shí),我們會(huì)得到類似于如下所示的輸出:
http://wiki.jikexueyuan.com/project/struts-2/images/sturtsselecttag.jpg" alt="" />
現(xiàn)在讓我們仔細(xì)瀏覽上述情況
首先,選擇標(biāo)簽用于呈現(xiàn) HTML 選擇框。在第一個(gè)例子中,我們創(chuàng)建的是一個(gè)簡單的選擇框,帶有名字 "username" 和標(biāo)記 "username"。該選擇框會(huì)由包含 Mike,John 和 Smith 名字的列表填充。
在第二個(gè)例子中,我們的公司總部在美國。它也在亞洲和歐洲擁有全球辦公室。我們想在選擇框中顯示辦公室,但是我們想把全球辦公室按照洲名分組。這就是 optgroup 的方便之處。我們使用 s:optgroup 標(biāo)簽來創(chuàng)建一個(gè)新組。給這個(gè)組一個(gè)標(biāo)記和一個(gè)單獨(dú)的列表。
在第三個(gè)例子中,用到了組合框。組合框是輸入字段和選擇框的組合。用戶可以從選擇框中選擇一個(gè)值,然后輸入字段就會(huì)用用戶選取的值自動(dòng)填充。或者用戶也可以直接輸入一個(gè)值,那么選擇框中的值就不會(huì)被選中。
在我們的例子中有一個(gè)列出了星座的組合框。組合框只列出了四個(gè)星座,如果用戶的星座不在組合框中,用戶可以自己鍵入他自己的星座。我們還在選擇框中添加了一個(gè)標(biāo)題入口。標(biāo)題入口顯現(xiàn)在選擇框的頂部。在我們的例子中我們想顯示“請(qǐng)選擇”。如果用戶沒有做出任何選擇,那么我們假定值為 -1。在一些情況下,我們不希望用戶選取空值。在這種情況下,設(shè)置 "emptyOption" 屬性為 false。最后,在我們的例子中,我們提供了 "capricorn" 作為組合框的默認(rèn)值。
在上述例子中,我們做了一個(gè)比較來看頂部選擇框是否就是 Techical。如果是的話,那么會(huì)顯示 IT 和 Hardware。我們也需要給頂部框("name='Occupations')和底部框(doubleName='occupations2')設(shè)置名稱。