Struts2 表单和非表单标签
學習內容
Struts 2表單標簽
?Struts 2非表單標簽
能力目標
?熟練使用Struts 2表單標簽開發表單
?熟練使用Struts 2非表單標簽
?
本章簡介
上一章講述了ognl和Struts2標簽庫中的數據訪問標簽和邏輯控制標簽。本章將重點介紹Struts2標簽庫中的表單標簽和非表單標簽。
表單標簽主要用于生成HTML中的表單。
非表單標簽主要包含一些常用的功能標簽,例如顯示日期或樹形菜單。熟練使用Struts2標簽將大大簡化視圖頁面的代碼編輯工作,提高視圖頁面的維護效率。
核心技能部分?
?
7.1?表單標簽
?Struts的表單標簽,可分為兩種:form標簽本身和單個表單元素的標簽。form標簽本身的行為不同于表單元素標簽。Struts 2的表單元素標簽都包含了非常多的屬性,但有很多屬性完全是通用的。
7.1.1?表單標簽的通用屬性
所有表單標簽處理類都繼承了UIBean類,UIBean包含了一些通用屬性,這些通用屬性分成3種:
模板相關屬性。
?JavaScript相關屬性。
?通用屬性。
除了這些屬性之外,所有表單元素標簽都存在一個特殊的屬性:form,這個屬性引用表單元素所在的表單,通過該form屬性,可以實現表單元素和表單之間的交互。例如,我們可以通過${ parameters.form. id }來取得表單元素所在表單的ID。下面詳細列出這些表單標簽的通用屬性。
模板相關的通用屬性如下:
?templateDir:指定該表單所用的模板文件目錄。
?theme:指定該表單所用的主題。
?template:指定該表單所用的模板。
Javascript相關的通用屬性如下:
?onclick:指定鼠標在該標簽生成的表單元素上單擊時觸發的JavaScript函數。
?onmousedown:指定鼠標在該標簽生成的表單元素上按下時觸發的JavaScript函數。
?onmouseup:指定鼠標在該標簽生成的表單元素上松開時觸發的JavaScript函數。
?onmouseover:指定鼠標在該標簽生成的表單一元素上懸停時觸發的JavaScript函數。
?onmouseout:指定鼠標移出該標簽生成的表單元素時觸發的JavaScript函數。
?onfocus:指定該標簽生成的表單元素得到焦點時觸發的函數。
?onblur:指定該標簽生成的表單元素失去焦點時觸發的函數。
?onkeypress:指定單擊鍵盤上某個鍵時觸發的函數。
?onkeyup:指定松開鍵盤某個鍵時觸發的函數。
?onkeydown:指定按下鍵盤上某個鍵時觸發的函數。
?onselect:對下拉列表項等可以選擇表單元素,指定選中該元素時觸發的JavaScript函數。
?onchange:對于文本框等可以接受輸入的表單元素,指定當值改變時觸發的JavaScript函數。
因為HTML元素本身的限制,并不是每個HTML元素都可以觸發以上的所有函數。因此,上面的屬性并不是對Struts 2的每個標簽都有效。
Struts 2還允許為表單元素設置提示,但鼠標在這些元素上懸停時,系統將出現提示,
Struts 2將這種特性稱為Tooltip。與Tooltip相關的通用屬性如下:
?tooltip:設置此組件的Tooltip。
?tooltipIcon:設置Tooltip圖標的URL路徑。
?tooltipAboveMousePointer:是否在光標位置上顯示Tooltip。也可通過設置tooltipOffseY屬性,設置Tooltip與光標位置的垂直位移。
?tooltipBgColor:設置Tooltip的背景色。
?tooltipBgImg:設置Tooltip的背景圖片。
?tooltipBorderWidth:設置Tooltip邊框的寬度。
?tooltipBorderColor:設置Tooltip邊框的顏色。
?tooltipDelay:設置顯示Tooltip的時間延遲(單位是毫秒)。
?tooltipFixCoordinateX:設置固定Tooltip在指定的X坐標上,與tooltipSticky屬性結合時很有用。
?tooltipFixCoordinateY設置固定Tooltip在指定的Y坐標上,與tooltipSticky屬性結合時很有用。
?tooltipFontColor:設置Tooltip的字體顏色。
?tooltipFontFace:設置Tooltip的字體,例如verdana. ?geneva, ?sans-serif等。
?tooltipFontSize:設置Tooltip的字體大小,例如30px。
?tooltipFontWeight:設置Tooltip的字體是否使用粗體,可以接受normal和bold(粗體)兩個值。
?tooltipLeftOfMousePointer:設置是否在光標左側顯示Tooltip,默認是在右邊顯示。
?tooltipOffsetX:設置Tooltip相對光標位置的水平位移。
?tooltipOffsetY:設置Tooltip相對光標位置的垂直位移。
?tooltipOpacity:設置Tooltip的透明度,設置值可以是0(完全透明)和100(不透明)之間的數字。Opera瀏覽器不支持該屬性。
?tooltipPadding:指定Tooltip的內部間隔。例如,邊框和內容之間的間距。
?tooltipShadowColor:使用指定的顏色為Tooltip創建陰影。
?tooltipShadowWidth:使用指定的寬度為Tooltip創建陰影。
?tooltipStatic:設置Tooltip是否隨著光標的移動而移動。
?tooltipSticky:設置Tooltip是否一直停留在它初始的位置,直到另外一個Tooltip被激活,或者瀏覽者點擊了HTML頁面。
?tooltipStayAppearTime:指定一個Tooltip消失的時間間隔(毫秒),即使鼠標還在相關的HTML元素上不動。設置值<=0,就和沒有定義一樣。
?tooltipTextAlign:設置Tooltip的標題和內容的對齊方式,可以是right(右對齊)、left(左對齊)或justify(居中對齊)。
?tooltipTitle:設置Tooltip的標題文字。
?tooltipTitleColor:設置Tooltip的標題文字的顏色。
?tooltipWidth:設置Tooltip的寬度。
除此之外,Struts 2還有其他的通用屬性,用于設置表單元素的CSS樣式等。
?cssClass:設置該表單元素的class屬性。
?cssStyle:設置該表單一元素的style屬性,使用內聯的CSS樣式。
?title:設置表單元素title屬性。
?disabled:設置表單元素的disabled屬性。
?label:設置表單元素的label屬性。
?labelPosition:設置表單元素label所在位置,可接受的值為top(上面)和left(左邊),默認是在左邊。
?requiredposition:定義必填標記(默認以*作為必填標記)位于label元素的位置,可接受的值為left(左面)和right(右邊),默認是在右邊。
?name:定義表單一元素的name屬性,該屬性值用十與Action的屬性形成對應。
?required:定義是否在表單元素的label上增加必填標記(默認以*作為必填標記),設置為true時增加必填標記,否則不增加。
?tabIndex:設置表單元素的tabindex屬性。
?value:設置表單兀素的value屬性。
7.1.2 表單標簽的name和value屬性
對于表單元素而言,name和value屬性之間存在一個獨特的關系:因為表單元素的name屬性會映射到Action的屬性,當該表單對應的Action已經被實例化,且對應屬性有值時,表單元素會顯示出該屬性的值,該值就是表單元素的value值。
name屬性設置表單元素的名字,表單元素的名字實際上封裝著一個請求參數,而請求參數是被封裝到Action屬性的。因此,可以將該name屬性指定為你希望綁定值的表達式。 ???例如如下代碼:
<!--將下面文本框的值綁定到Action的person屬性的firstName屬性 -- >
??????<s:textfield ?name="person.firstName”/>
大多數場景下,我們希望表單元素里可以顯示出對應Action的屬性值,此時就可以通過指定該表單元素的value屬性來完成該工作。例如使用如下代碼:
????<!--使用表達式生成表單元素的值一>
??????<s:textfield name=”person.firstName”?value=”${person.firstName}”/>
事實上,因為name和value屬性的特殊關系,如果我們使用Struts 2的標簽庫,則無需指定value屬性,因為Struts 2會為我們處理這些。
對于如下代碼:
????<!一將下面文本框的值綁定到Action的person屬性的firstName屬性一>
??????<s:textfield name=”person.firstName"/>
雖然上面的文本框沒有指定value屬性,但Struts 2一樣會在該文本框中輸出對應Action里的屬性值。
7.1.3?常用表單標簽
1. ?<s:form>標簽
該標簽的主要屬性是action和namespace,例如下面的代碼:
<s:form action="tag1.action" namespace="/tags">
</s:form>
生成的HTML代碼如下所示:
<form action="tag1.action" method="post">
2.?文本類標簽
此類標簽包括文本框(<s:textfield?/>)、密碼框(<s:password?/>)、文本區域(<s:textarea>),下面是一個簡單的示例。
示例7.1
<body> <s:form action="tag1" namespace="/tags"> <s:textfield name="loginname" label="登錄名稱"></s:textfield> <s:password name="pwd" label="登錄密碼"></s:password> <s:textarea name="info" label="個人簡介" cols="28" rows="10"></s:textarea> <s:submit value="提交"></s:submit> <s:reset value="重填"></s:reset> </s:form></body>?
圖7.1.1 文本類標簽
上述代碼生成的HTML如下所示。
<body> <form action="/Struts8/tags/tag1.action" method="post"> <table class="wwFormTable"> <tr> <td class="tdLabel"> <label for="tag1_loginname" class="label">登錄名稱:</label></td> <td> <input type="text" name="loginname"/></td> </tr> <tr><td class="tdLabel"><label for="tag1_pwd" class="label">登錄密碼:</label> </td> <td> <input type="password" name="pwd" id="tag1_pwd"/></td> </tr> <tr><td class="tdLabel"> <label for="tag1_info" class="label">個人簡介:</label></td><td> <textarea name="info" cols="28" rows="10"></textarea> </td> </tr> <tr><td colspan="2"><input type="submit" value="提交"/></td> </tr> <tr><td colspan="2"><input type="reset" value="重填"/></td> </tr> </table> </form> </body>3.?checkboxlist標簽
checkboxlist標簽可以一次創建多個復選框,用于一次生成多個HTML標簽中的<input type="checkbox"…/>,它根據list屬性指定的集合來生成多個復選框。因此,使用該標簽指定一個list屬性。除此之外,其他屬性大部分是通用屬性,此處不再贅述。
除此之外,checkboxlist表單還有兩個常用屬性:
?listKey:該屬性指定集合元素中的某個屬性(例如集合元素為Person實例,指定Person實例的name屬性)作為復選框的value。如果集合是Map,則可以使用key和value值分別代表Map對象的key和value作為復選框的value 。
?listValue:該屬性指定集合元素中的某個屬性(例如集合元素為Person實例,指定Person實例的name屬性)作為復選框的標簽。如果集合是Map,則可以使key和value值分別代表Map對象的key和value作為復選框的標簽。
下面是使用該標簽的代碼示例,其中分別使用了簡單集合、簡單Map對象、集合里放置Java實例來創建多個復選框。
下面是該JSP頁面代碼:
<body> <h2>使用checkboxlist標簽</h2> <s:form> <!-- 使用字符串集合生成多個復選框 --> <s:checkboxlistlist="{'JSP','Servlet','Struts2','Ajax'}" name="skills" label="熟悉技術"> </s:checkboxlist> <!-- 使用Map對象來生成多個復選框 --> <s:checkboxlist name="skillsarea" label="你所關注的技術領域"list="#{'java':'JAVA', '.net':'.NET', 'db':'Database','ajax':'Ajax'}"listKey="key"listValue="value"/> </s:form> </body>在上面代碼中,簡單集合對象和簡單Map對象都是通過OGNL表達式直接生成,但實際使用中一般是從后臺查詢出一個javaBean集合然后傳遞到頁面進行顯示。該JavaBean的類代碼如下:
public class?Book
{
private int id;
?????private ?String bookName;
private ?String author;
//getter setter方法省略…….
}
Jsp頁面代碼:
<%//模擬后臺查詢到的數據 并轉發到頁面List books = new ArrayList();books.add(new Book(1,"殺殺人,喝喝酒---水滸傳","施耐庵"));books.add(new Book(2,"瘋狂的猴子---西游記","吳承恩"));books.add(new Book(3,"瘋狂的石頭---紅樓夢","曹雪芹"));books.add(new Book(4,"大哥,我們動手吧---三國演義","羅貫中"));request.setAttribute("bs",books);%><s:form> <!-- 使用字符串集合生成多個復選框 --> <s:checkboxlistlist="{'JSP','Servlet','Struts2','Ajax'}" name="skills" label="熟悉技術"> </s:checkboxlist> <!-- 使用Map對象來生成多個復選框 --> <s:checkboxlist name="skillsarea" label="你所關注的技術領域"list="#{'java':'JAVA', '.net':'.NET', 'db':'Database','ajax':'Ajax'}"listKey="key"listValue="value"/><s:checkboxlist label="你喜歡的圖書" name="lb" list="#attr.bs"listKey="id" listValue="bookName" value="1"></s:checkboxlist> </s:form>當我們在瀏覽器中瀏覽該頁面時,將看到如圖7.1.2所示的頁面。
?
圖7.1.2 checklist標簽
生成的HTML代碼如下所示:
<html><head><base href="http://localhost:8080/test23/"><title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --></head><body><form id="" action="/test23/" method="post"> <table class="wwFormTable"> <!-- 使用字符串集合生成多個復選框 --><tr><td class="tdLabel"><label for="_skills" class="label">熟悉技術:</label></td><td > <input type="checkbox" name="skills" value="JSP" id="skills-1"/> <label for="skills-1" class="checkboxLabel">JSP</label> <input type="checkbox" name="skills" value="Servlet" id="skills-2"/> <label for="skills-2" class="checkboxLabel">Servlet</label> <input type="checkbox" name="skills" value="Struts2" id="skills-3"/> <label for="skills-3" class="checkboxLabel">Struts2</label> <input type="checkbox" name="skills" value="Ajax" id="skills-4"/> <label for="skills-4" class="checkboxLabel">Ajax</label> <input type="hidden" id="__multiselect__skills" name="__multiselect_skills" value="" /> </td> </tr><!-- 使用Map對象來生成多個復選框 --> <tr><td class="tdLabel"><label for="_skillsarea" class="label">你所關注的技術領域:</label></td><td > <input type="checkbox" name="skillsarea" value="java" id="skillsarea-1"/> <label for="skillsarea-1" class="checkboxLabel">JAVA</label> <input type="checkbox" name="skillsarea" value=".net" id="skillsarea-2"/> <label for="skillsarea-2" class="checkboxLabel">.NET</label> <input type="checkbox" name="skillsarea" value="db" id="skillsarea-3"/> <label for="skillsarea-3" class="checkboxLabel">Database</label> <input type="checkbox" name="skillsarea" value="ajax" id="skillsarea-4"/> <label for="skillsarea-4" class="checkboxLabel">Ajax</label> <input type="hidden" id="__multiselect__skillsarea" name="__multiselect_skillsarea" value="" /> </td> </tr><tr><td class="tdLabel"><label for="_lb" class="label">你喜歡的圖書:</label></td><td > <input type="checkbox" name="lb" value="1" id="lb-1" checked="checked"/> <label for="lb-1" class="checkboxLabel">殺殺人,喝喝酒---水滸傳</label> <input type="checkbox" name="lb" value="2" id="lb-2"/> <label for="lb-2" class="checkboxLabel">瘋狂的猴子---西游記</label> <input type="checkbox" name="lb" value="3" id="lb-3"/> <label for="lb-3" class="checkboxLabel">瘋狂的石頭---紅樓夢</label> <input type="checkbox" name="lb" value="4" id="lb-4"/> <label for="lb-4" class="checkboxLabel">大哥,我們動手吧---三國演義</label> <input type="hidden" id="__multiselect__lb" name="__multiselect_lb" value="" /> </td> </tr> </table></form> </body> </html>從圖7.1.2中可以看出,通過指定checkboxlist標簽的listKey和listValue屬性,可以分別指定多個復選框的value和標簽。
4.?radio標簽
該標簽與上面的checkboxlist標簽的用法幾乎完全相同,都是通過指定list、listKey、listValue等屬性來生成HTML元素。不同的是,checkboxlist標簽生成的是復選框,而radio標簽生成的是單選框。
下面我們看一個實例,代碼如下所示:
示例7.2
<body>
<h2>使用radio標簽</h2>
<s:form>
<!-- 使用字符串集合來生成多個單選框 -->
<s:radio
?? list="{'JSP','Servlet','Struts2','Ajax'}" name="skills"
?????label="熟悉技術">
</s:radio>
<!-- 使用Map對象來生成多個單選框 -->
<s:radio name="skillsarea" label="你所關注的技術領域"
????list="#{'java':'JAVA', '.net':'.NET', 'db':'Database','ajax':'Ajax'}"
??listKey="key"
??listValue="value"
??value="'java'"/>
</s:form>
</body>
該頁面的運行效果如圖7.1.3所示。
?
<body> <h2>使用radio標簽</h2> <form action="/Struts8/s-radio.jsp" method="post"> <table class="wwFormTable"> <!-- 使用字符串集合來生成多個單選框 --> <tr><td class="tdLabel"> <label for="s-radio_skills" class="label">熟悉技術:</label></td><td> <input type="radio" name="skills" value="JSP"/> <label for="s-radio_skillsJSP">JSP</label> <input type="radio" name="skills" value="Servlet"/> <label for="s-radio_skillsServlet">Servlet</label> <input type="radio" name="skills" value="Struts2"/> <label for="s-radio_skillsStruts2">Struts2</label> <input type="radio" name="skills" value="Ajax"/> <label for="s-radio_skillsAjax">Ajax</label></td> </tr> <!-- 使用Map對象來生成多個單選框 --> <tr><td class="tdLabel"><label for="s-radio_skillsarea" class="label"> 你所關注的技術領域:</label></td><td> <input type="radio" name="skillsarea" checked="checked" value="java"/> <label for="s-radio_skillsareajava">JAVA</label> <input type="radio" name="skillsarea" value=".net"/> <label for="s-radio_skillsarea.net">.NET</label> <input type="radio" name="skillsarea" value="db"/> <label for="s-radio_skillsareadb">Database</label> <input type="radio" name="skillsarea" value="ajax"/> <label for="s-radio_skillsareaajax">Ajax</label> </td> </tr> </table> </form> </body>5.?select標簽
select標簽用于生成一個下拉列表框,通過為該元素指定list屬性,系統會使用list屬性指定的集合來生成下拉列表框的選項。這個list屬性指定的集合,既可以是普通集合,也可以是Map對象,還可以是集合元素是對象的集合。
除此之外,select表單還有如下幾個常用屬性:
??listKey:該屬性指定集合元素中的某個屬性(例如集合元素為Person實例,指定Person實例的name屬性)作為復選框的value。如果集合是Map,則可以使用key和value值分別代表Map對象的key和value作為復選框的value。
??listValue:該屬性指定集合元素中的某個屬性(例如集合元素為Person實例,指定Person實例的name屬性)作為復選框的標簽。如果集合是Map ,則可以使用key和value值分別代表Map對象的key和value作為復選框的標簽。
??multiple:設置該列表框是否允許多選。
從上面介紹中可以看出,select標簽的用法與checkboxlist標簽的用法非常相似。
下面我們看一個實例,其中分別使用了簡單集合、簡單Map對象、集合里放置Java實例來創建多個復選框。代碼如下所示:
示例7.3
?
?????<body>
??<h2>使用select標簽</h2>
<!-- 使用字符串集合來生成下拉列表框?-->
<s:elect list="{'Struts2從入門到精通' , 'Spring2開發寶典' , 'Ajax實戰'}"
?????name="books" label="圖書列表">
</s:select>
<br><br>
<!-- 使用簡單對象來生成下拉列表框?-->
<s:select name="books_map" label="圖書列表"
????list="#{'struts2':'Struts2從入門到精通', 'spring2':'Spring2開發寶典',
?????????????'ajax':'Ajax實戰'}"
listKey="key"
listValue="value"/>
<br><br>
<s:select name="b" label="圖書列表"
??????????multiple="true"
????????????list="#attr.bs"
??????????listKey="id"
????????????listValue="bookName" value="2"/>
??</body>
?
該頁面的運行效果如圖7.1.4所示。
?
圖7.1.4 ?使用select標簽
注意:可以使用select的value屬性設置<s:select>標簽生成下拉框時的初始值,默認情況下將以生成下拉框的第一項為初始值。
6.?doubleselect標簽
????doubleselect標簽會生成一個級聯列表框(會生成兩個下拉列表框),當選擇第一個下
拉列表框時,第二個下拉列表框的內容會隨之改變。
????因為兩個都是下拉選擇框,因此需要指定兩個下拉選擇框的選項,因此有如下常用的屬性:
?list:指定用于輸出第一個卜拉列表框中選項的集合。
?listKey:該屬性指定集合元素中的某個屬性(例如集合元素為Person實例,指定Person實例的name屬性)作為第一個下拉列表框的value。如果集合是Map,則可以使用key和value值分別代表Map對象的key和value作為復選框的value。
?listValue:該屬性指定集合元素中的某個屬性(例如集合元素為Person實例,指定Person實例的name屬性)作為復選框的標簽。如果集合是Map,則可以使用key和value值分別代表Map對象的key和value作為第一個下拉列表框的標簽。
?doubleList:指定用于輸出第一個下拉列表框中選項的集合。
?doubleList Key:該屬性指定集合元素中的某個屬性(例如集合元素為Person實例,指定Person實例的name屬性)作為第一個下拉列表框的value。如果集合是Map,則可以使用key和value值分別代表Map對象的key和value作為復選框的value。
?doubleList Value:該屬性指定集合元素中的某個屬性(例如集合元素為Person實例,指定Person實例的name屬性)作為復選框的標簽。如果集合是Map,則可以使用key和value值分別代表Map對象的key和value作為第一個下拉列表框的標簽。
?doubleName:指定第二個下拉列表框的name屬性。
?cssStyle:設置第一級下拉框的樣式。
?doubleCssStyle:設置第二級下拉框的樣式。
下面看一個實例,代碼如下所示:
示例7.4
(1)創建用于描述部門的實體類。
?
public class DeptInfo {
?
private String deptId;
private String deptName;
private Set<EmpInfo> empSet = new HashSet<EmpInfo>();//包含多個職工
//無參構造函數
public DeptInfo() {
super();
}
//有參構造函數
public DeptInfo(String deptId, String deptName) {
super();
this.deptId = deptId;
this.deptName = deptName;
}
//getter setter 方法省略......
}
(2)創建用于描述職工的實體類。
public class EmpInfo { private String empId; private String empName; //無參構造函數 public EmpInfo() { super(); } //有參構造函數 public EmpInfo(String empId, String empName) { super(); this.empId = empId; this.empName = empName; } //getter setter 方法省略...... }(3)創建業務邏輯控制器。
public class DoubleSelectAction extends BaseAction { //用于封裝用戶請求的部門編號 private String deptId; //用于封裝用戶請求的職工編號 private String empId; public String execute() throws Exception { //獲取輸出對象 PrintWriter out = super.getResponse().getWriter(); out.println("<h2>你選擇的信息是: <hr/>部門編號: " + this.deptId + "<br/>"); out.println(" 職工編號: " + this.empId + "</h2>"); return null; } public String getDeptId() { return deptId; } public void setDeptId(String deptId) { this.deptId = deptId; } public String getEmpId() { return empId; } public void setEmpId(String empId) { this.empId = empId; } }(4)創建jsp頁面。
<body><%DeptInfo d1 = new DeptInfo("D001","銷售部");DeptInfo d2 = new DeptInfo("D002","財務部");EmpInfo e1 = new EmpInfo("E001","張三");EmpInfo e2 = new EmpInfo("E002","李四");EmpInfo e3 = new EmpInfo("E003","王五");EmpInfo e4 = new EmpInfo("E004","趙六");d1.getEmpSet().add(e1);d1.getEmpSet().add(e2);d2.getEmpSet().add(e3);d2.getEmpSet().add(e4);//構造map,用于存放所有部門Map map = new HashMap();map.put(d1,d1.getEmpSet());map.put(d2,d2.getEmpSet());request.setAttribute("map",map);%><s:form action="doubleSelect" namespace="/test">級聯下拉框:<hr/><s:doubleselect cssStyle="width:130px" list="#request.map.keySet()" listKey="deptId" listValue="deptName" name="deptId"doubleCssStyle="width:130px" doubleList="#request.map[top]" doubleListKey="empId" doubleListValue="empName" doubleName="empId"/><hr><s:submit value="提交"/> </s:form></body>運行以上Jsp頁面,結果如圖7.1.5所示,
?
圖7.1.5 DoubleSelect標簽的使用
在圖7.1.5中,對第一級“部門”下拉框做任意選擇時,第二級“職工”下拉框內容將做相應的級聯改變。
單擊“提交”按鈕,提交到DoubleSelectAction控制器,運行結果如圖7.1.6所示。
?
圖7.1.6 級聯下拉框提交
注意:
使用doubleselect標簽時,必須放在<<s:form…/>標簽中使用,且必須為該<s:form .../>標簽指定action屬性?
7. optiontransferselect標簽
Optiontransferselect創建兩個選項用來轉移下拉列表項,該標簽會生成兩個<select/>標簽,并且會生成系列的按鈕,這系列的按鈕可以控制選項在兩個下拉列表之間移動、升降。當提交該表單時,兩個<select/>標簽的請求參數都會被提交。
因為該標簽會生成兩個下拉列表框,因此需要分別指定兩個下拉列表框中的集合、Label等屬性,下面是該標簽常用的屬性。
?addAllToLeftLabel:設置全部移動到左邊按鈕上的文本。
?addAllToRightLabel:設置全部移動至右邊按鈕上的文本。
?addToLeftLabel:設置向左移動按鈕上的文本。
?addToRightLabel:設置向右移動按鈕上的文本。
?a1lowAddAllToLeft:設置是否出現全部移動到左邊的按鈕。
?a1lowAddAllToRight:設置是否出現全部移動到右邊的按鈕。
?a1lowAddToLeft:設置是否出現移動到左邊的按鈕。
?a1lowAddToRight:設置是否出現移動到右邊的按鈕。
?leftTitle:設置左邊列表框的標題。
?rightTitle:設置右邊列表框的標題。
?a1lowSelectAll:設置是否出現全部選擇按鈕。
?selectAllLabel:設置全部選擇按鈕上的文本。
?doubleList:設置用于創建第二個下拉選擇框的集合。
?doubleListKey:設置創建第二個下拉選擇框的選項value的屬性。
?doubleListValue:設置創建第二個下拉選擇框的選項label的屬性。
?doubleName:設置第二個下拉選擇框的name屬性。
?doubleValue:設置第二個下拉選擇框的value屬性。
?doubleMultiple:設置第二個下拉選擇框是否允許多選。
?list:設置用于創建第一個下拉選擇框的集合。
?listKey:設置創建第一個下拉選擇框的選項value的屬性。
?listValue:設置創建第一個下拉選擇框的選項label的屬性。注意此處的list , ?doubleList , ??listKey , ?doubleListKey , ?listValue和doubleListValue非常類似于checkboxlist標簽中list, listKey和listValue的用法,只是此處用于生成兩個下拉列表框,而前者是生成多個復選框而已。
?name:設置第一個下拉選擇框的name屬性。
?value:設置第一個下拉選擇框的value屬性。
?multiple:設置第一個下拉選擇框是否允許多選。
下面代碼是使用optiontransferselect標簽的示范,它分別指定了兩個簡單集合來生成兩個下拉列表框的列表項。下面是使用optiontransferselect標簽的代碼:
<!-- 使用簡單集合對象來生成可移動的下拉列表框 其中list指定生成第一個下拉選擇框的選項的集合
??????????doubleList指定生成第二個下拉選擇框的選項的集合-->
??????<s:optiontransferselect
????????label="請選擇你喜歡的圖書"
??????????????name="cnb00k"
??????????leftTitle="中文圖書"
????????rightTitle="外文圖書"
????????list="{'Spring2.。寶典','輕量級J2EE企業應用實戰','基于J2EE的Ajax寶典'}"
??????????multiple="true"
????????addToLeftLabel="向左移動"
????????selectAllLabel="全部選擇"
??????????addAllToRightLabel="全部右移"
????????????headerKey="cnKey"
????????headerValue="一選擇中文圖書一"
??????????emptyOption="true"
??????????doubleList="{'Expert One一on一One J2EE Design and Development’,
????????????????,'JavaScript:The Definitive Guide’}"
??????????????doubleName="enBook"
doubleHeaderKey="enKey"
doubleHeaderValue="-一選擇外文圖書-一"
doubleEmptyOption="true"
doubleMultiple="true"></s:optiontransferselect>
在瀏覽器中瀏覽該頁面,將看到如圖7.1.7所示的頁面。
?
圖7.1.7 ?optiontransferselect標簽
8.?token標簽
<s:token>標簽用于避免刷新頁面時多次提交表單,通過借助于TokenInterceptor攔截器來實現阻止頁面重復提交。當Jsp使用<s:token/>標簽的時候,Struts2會建立一個GUID(全局唯一的字符串)并放在Session中,同時在表單中添加一個隱藏域。而TokenInterceptor攔截器會攔截用戶的請求,并判斷客戶端form提交的token與session中保存的token是否相等 ,如果相等,則執行action對應的方法并清空;否則,攔截器將直接返回invalid.token結果,不會執行Action對應的方法。示例7.5演示了使用token標簽的過程。
示例7.5
(1)創建用于處理用戶注冊的業務邏輯控制器Action.
public class RegAction extends ActionSupport { private String uid; private String pwd; public String execute() throws Exception { HttpServletResponse response = (HttpServletResponse)ActionContext.getContext().get(ServletActionContext.HTTP_RESPONSE); response.setContentType("text/html;charset=gbk"); response.setCharacterEncoding("gbk"); PrintWriter out = response.getWriter(); Date today = new Date(); out.println("<h2>用戶注冊信息如下: <hr/>用戶名:" + this.uid + "<br/>密 碼:" + this.pwd+"<hr>"); out.println("正在進行注冊 " + today.toLocaleString() + "..."); return null; } public String getUid() { return uid; } public void setUid(String uid) { this.uid = uid; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } }(2)創建Jsp頁面,命名為“reg.jsp”。
?
<body><font color="red"><s:actionerror/></font><s:form action="reg" οnsubmit="return check()"><!-- 加入token標簽 --><s:token/>填寫會員注冊信息:<hr/>用戶名:<s:textfield name="uid"/><br/>密 碼:<s:password name="pwd"/><br>確認密碼:<s:password name="surePwd"/><br><s:submit value="提交"></s:submit><s:reset value="重置"></s:reset></s:form> <script type="text/javascript"> function $(elementName) { return document.getElementById(elementName); } function check() { if($("reg_uid").value == "") { alert("用戶名不能為空!"); $("reg_uid").focus(); return false; } if($("reg_pwd").value == "") { alert("密碼不能為空!"); $("reg_pwd").focus(); return false; } if($("reg_pwd").value != $("reg_surePwd").value) { alert("兩次密碼不一致!"); $("reg_surePwd").focus(); return false; } return true; } </script></body>(3)編寫用于顯示重復提交錯誤信息的資源文件,創建application_zh.properties中文資源文件,將文件存放于WEB-INF/classes目錄下,內容為“Struts.messages.invalid.token=表單已提交,不能重復提交”,并使用native2Ascii命令進行轉化。
(4)在struts.xml中配置token攔截器。
?
<struts><constant name="struts.ui.theme" value="simple" /><constant name="struts.custom.i18n.resources" value="application" /> <package name="mypackage" extends="struts-default"> <!-- 定義攔截器棧--> <interceptors> <interceptor-stack name="tokenStack"><interceptor-ref name="token" /> <!-- 使用token攔截器--><interceptor-ref name="defaultStack" /><!-- 使用默認攔截器--></interceptor-stack></interceptors> <!-- 將攔截器棧token作為默認攔截器,則攔截器棧中定義的所有攔截器將作用于本包的所有Action--><default-interceptor-ref name="tokenStack" /><!-- 配置注冊Action--> <action name="reg" class="com.zzab.entity.RegAction"> <!-- 當用戶重復提交表單時,流程轉到stoken.jsp--><result name="invalid.token">/stoken.jsp</result></action></package></struts>運行reg.jsp,運行效果如圖7.1.8所示。
?
圖7.1.8 登錄頁面
單擊【提交】按鈕后就執行了對應的Action,如圖7.1.9所示。
?
圖7.1.9 執行Action
此時刷新頁面,則根據token攔截器配置,將進入invalid.token邏輯結果,即reg.jsp。該頁面會通過<s:actionerror/>標簽讀取application_zh.prooperties中文資源文件的內容并顯示。如圖7.1.10所示。
?
圖7.1.10 不能重復提交
7.1?非表單標簽
7.2.1?Datetimepicker標簽?
datetimepicke:標簽生成一個日期、時間下拉選擇框,當我們使用該日期、時間選擇框選擇某個日期、時間時,系統會自動將選中的日期、時間輸入指定文本框。
系統將指定日期、時間輸入指定文本框時,必須轉換成日期、時間字符串,為了設置該字符串的格式,必須使用日期、時間的格式符。datetimepicker支持如下幾個格式符:
#dd:以兩位數字來顯示當前日期的日。
#d:試圖以一位數字來顯示當前日期的日,它不會使用兩位數字。
#MM:以兩位數字來顯示當前日期的月。
#M:試圖以一位數字來顯示當前日期的月,它不會使用兩位數字。
#YYYY:以4位數字來顯示當前日期的年。
#YY:以兩位數字來顯示當前日期的年。
#y:以一位數字來顯示當前日期的年的最后一位。
使用該標簽時,有如下幾個常用屬性:
?displayFormat:該屬性指定日期的顯示格式,例如,可以使用dd/MM/yyyy作為日期格式。
?displayWeeks:該屬性指定該日歷能顯示星期數。
?endDate:指定日期集的最后可用日期。例如2941-10-12,一旦指定了該日期,則后面的日期不可用。
?formatLength:指定日期顯示的格式,這些格式值就是DateFormat中的格式,該屬性支持的值有long, ?short, ?medium和full 4個值。
?language:指定日期顯示的Locale,例如需要指定簡體中文,則指定zh_ CN。
?startDate:指定日期集的最后可用日期。例如1941-10-18,一旦指定了該日期,則前面的日期不可用。
?toggleDuration:指定日期選擇框出現、隱藏的切換時間。
?toggletype:指定日期選擇框出現、隱藏的方式,可以選擇plain, wipe, explode和fade 4個值。
?type:指定日期選擇框的類型,支持的值有date和time,分別代表日期選擇框、時間選擇框。
?value:指定當前日期、時間。可使用today來代表今天。
?weekStartsOn:指定口期選擇框中哪一天才是一周的第一天。周日是0,周六是6。
在使用datetimepicker標簽之前,首先要通過MyEclipse導入struts2-dojo-plugin-2.2.1.jar文件,因為該標簽包含在這個Jar文件中。
示例7.6
下面我們看一個該標簽的實例,代碼如下所示: ?
<s:form theme="simple">日期選擇部件,指定toggleType屬性,且指定value="today"<br><sx:datetimepicker name="order.date" label="購買日期" toggleType="explode"value="%{'today'}"/><hr>日期選擇部件,指定了format屬性<br><sx:datetimepicker name="order.date" label="購買日期" displayFormat="yyyy年MM月dd日"/><hr>日期選擇部件,指定了weekStartOn屬性<br><sx:datetimepicker name="order.date" label="購買日期" displayFormat="yyyy年MM月dd日" weekStartsOn="2"/><hr> </s:form>在瀏覽器中瀏覽該頁面,將看到如圖7.1.11所示的頁面,在圖7.1.11中,如果我們單擊那些文本框后選擇日期,將出現一個日期選擇框。如果我們指定weekStartsOn屬性,則可以設置口期選擇框中每周中哪一天才會是第一天。
?
圖7.1.11?日期控件
?7.2.2?tree標簽和treenode標簽
這兩個標簽主要用來生成一個樹形結構,例如常見的樹形菜單、樹形列表等。tree標簽表示樹根,treenode標簽表示樹的的節點,需要嵌套在tree標簽中。在使用這兩個標簽之前,也需要通過MyEclipse導入struts2-dojo-plugin-2.2.1.jar文件。
示例7.7
下面是一個使用tree標簽和treenode標簽生成靜態樹形列表的示例。
<%@ page contentType="text/html; charset=utf-8" language="java" %> <%@taglib prefix="s" uri="/struts-tags" %> <%@ taglib prefix="sdt" uri="/struts-dojo-tags"%> <html> <sdt:head parseContent="true"/> <title>使用tree和treenode標簽生成靜態樹</title> <body> <h3>使用tree和treenode標簽生成靜態樹</h3> <sdt:tree label="計算機編程系列圖書" id="books"><sdt:treenode label="JAVA編程系列" id="java"><sdt:treenode label="Spring2.0開發寶典" id="spring"/><sdt:treenode label="Struts2.0權威指南" id="struts"/><sdt:treenode label="Hibernate3從入門到精通" id="hibernate"/></sdt:treenode><sdt:treenode label="Ajax編程系列" id="ajax"><sdt:treenode label="JavaScript一百例" id="javascript"/><sdt:treenode label="Ajax實戰" id="ajaxsz"/></sdt:treenode> </sdt:tree> </body> </html>通過上述代碼可以看到,tree和treenode標簽都是通過label屬性來設置樹形列表文本,此案例樹形列表中的文本數據都寫死到里面了,實際應用中通常是從數據庫查詢出來并由Action返回到頁面中。運行效果如圖7.1.12所示。
?
圖7.1.12 樹形列表
本章總結
?Struts的表單標簽
可分為兩種:form標簽本身和單個表單元素的標簽。form標簽本身的行為不同于表單元素標簽。Struts 2的表單元素標簽都包含了非常多的屬性,但有很多屬性完全是通用的。
?非表單標簽
(1)datetimepicke:標簽生成一個日期、時間下拉選擇框,當我們使用該日期、時間選擇框選擇某個日期、時間時,系統會自動將選中的日期、時間輸入指定文本框。
(2)tree標簽和treenode標簽。這兩個標簽主要用來生成一個樹形結構,例如常見的樹形菜單、樹形列表等。tree標簽表示樹根,treenode標簽表示樹的的節點,需要嵌套在tree標簽中。
任務實訓部分
1:臟字過濾
訓練技能點
?token標簽
?token攔截器
??需求說明
在第五章的任務實現部分,我們實現了對評論進行臟字過濾功能,現在要求增加防止表單重復提交的功能。
2:簡易計算器
訓練技能點
?OGNL
?表單標簽
??需求說明
在前面的章節中我們實現了一個簡易計算器案例,現在要求使用Struts 2表單標簽和OGNL對該案例進行重構。
3:動態生成樹
訓練技能點
?OGNL
?Tree標簽
??需求說明
要求使用Struts 2 tree標簽和OGNL動態生成數據。
實現思路
(1)?創建用于查詢樹節點信息的Action,命名為TreeAction.java。
public class TreeAction extends ActionSupport {? public String execute() { Object[][] obj = { ??{"1","0","短信平臺管理","#"}, ??{"2","1","用戶管理","#"}, ??{"3","1","員工管理","#"}, ??{"4","1","短信管理","#"}, ??{"5","2","用戶權限管理","userRight.jsp"}, ??{"6","2","用戶列表","userList.jsp"}, ??{"7","3","員工信息列表","empList.jsp"}, ??{"8","3","員工信息修改","empUpdate.jsp"}, ??{"9","4","接收短信","acceptMessage.jsp"}, ??{"10","4","短信統計","messageCount.jsp"} ??}; ?ServletActionContext.getRequest().setAttribute("obj",obj);? return SUCCESS; }}
(2)?配置TreeAction。
<action name="treeaction" class="com.zzzy.action.TreeAction"> <result>/sx_tree.jsp</result> </action>
(3)?創建sx_tree.jsp。
<sx:tree label="短信管理平臺">? <s:iterator id="row" value="#request.obj">? <s:if test="#row[1]==1">? <sx:treenode label="%{#row[2]}">? <s:iterator id="row1" value="#request.obj">? <s:if test="#row1[1]==#row[0]">? <sx:treenode label="<a href=%{#row1[3]}>%{#row1[2]}</a>" />? </s:if>? </s:iterator>? </sx:treenode>? </s:if>? ? </s:iterator>? </sx:tree>
鞏固練習
一、選擇題
1. 以下()不屬于Struts 2的表單標簽。
A.?<s:textfield>
B.?<s:textarea>
C.?<s:submit>
D.?<s:tree>
2. token標簽的作用是()。
A.?顯示錯誤消息
B.?校驗表單數據
C.?防止重復提交
D.?生成相應的html標簽
3. Datetimepicker標簽的()屬性用來指定該日歷能顯示星期數。
A. ?displayFormat
B.??endDate
C.??formatLength
D.??displayWeeks
4. 以下對checkboxlist標簽描述正確的是()。
A.?其list屬性指定要循環的集合
B.?該標簽使用集合生成一組復選框
C.?Listkey指定集合元素中的某個屬性作為復選框的文本
D.?listvalue指定集合元素中的某個屬性作為復選框的value
5. 以下對tree 和treenode標簽描述錯誤的是()。
A.?兩個標簽主要用來生成一個樹形結構。
B.?tree標簽表示樹根。
C.?treenode標簽表示樹的的節點。
D.?可以通過treenode 的list屬性指定一個集合并生成一組樹節點。?
二、上機練習
?在本章的核心任務部分,我們使用doubleselect標簽實現了一個省市級聯列表框功能,現在要求把省市級聯改成樹形列表的形式。
?
總結
以上是生活随笔為你收集整理的Struts2 表单和非表单标签的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Struts2标签库和OGNL
- 下一篇: 高新面试系列 性格篇