html:select標(biāo)簽生成一個select元素。是單選還是多選取決于該標(biāo)簽的multiple屬性。如果指定了multiple= "true"則為多選,此時對應(yīng)的屬性應(yīng)該是一個數(shù)組。如果沒有指定multiple="true"則為單選,此時對應(yīng)的屬性應(yīng)該是標(biāo)量。
注意:為了正確的處理沒有做任何的選擇的情況,在ActionForm中的reset()方法中必須將標(biāo)量屬性設(shè)置為默認(rèn)值而將數(shù)組的長度置為0。
另外的一個重要問題就是struts如何生成option元素了,這個任務(wù)struts交給了html:option、html:options和html:optionsCollection三個標(biāo)簽。
html:option標(biāo)簽
html:option標(biāo)簽生成一個HTML的option元素。該標(biāo)簽必須嵌在html:select標(biāo)簽中。它的顯示文本來自其標(biāo)簽體,也可以來自于資源文件。它的value屬性用來指定什么值將要被提交。
<html:option value="one">one</html:option> <html:option value="two">two</html:option>
html:options標(biāo)簽
html:options標(biāo)簽生成多個HTML的option元素。該標(biāo)簽必須嵌在html:select標(biāo)簽中。而且工作方式有些特殊,它的name與property屬性和其它標(biāo)簽的name與property屬性意義不一致,讓我們具體看一下它的工作方式。
指定collection屬性
讓我通過示例來介紹在指定collection屬性時該標(biāo)簽的工作方式,首先要說明selectForm中的persons和listForm中的persons完全一致。請參見bean:define標(biāo)簽。
下面的代碼先利用bean:define標(biāo)簽將selectForm中的persons取到page作用域中,然后html:options標(biāo)簽再 依據(jù)collection="personCollection"選中這個persons并將其中的每一個對象(Person類型)生成一個option 元素。該標(biāo)簽的property="id"表示persons中的對象(Person類型)的id屬性將作為option元素的value值。該標(biāo)簽的 labelProperty="name"表示persons中的對象(Person類型)的name屬性將作為option元素的label值。
當(dāng)這個select提交時所選擇的值將被提交到selectForm(name="selectForm")中的person對象(這是在 SelectForm中聲明的一個Person類型的域?qū)iT用來接收提交的值)的id屬性中(property="person.id")。
<bean:define property="persons"/> <html:select property="person.id" size="1"> <html:options collection="personCollection" property="id" labelProperty="name"/> </html:select>
沒有指定collection屬性
讓我通過示例來介紹沒有指定collection屬性時該標(biāo)簽的工作方式,先來看看ids和names的定義:
private List<String> ids = null; private List<String> names = null;
上面的代碼來自SelectForm,其中ids是一個String的列表,names也是一個String的列表。我們暫時假定這兩個列表含有相 同數(shù)目的元素。有了這些讓我們開始介紹下面的代碼。html:options標(biāo)簽用ids中的第i個值作為option元素的value值同時使用 names中相同位置的值(第i個值)作為option元素的label值。如果ids比names長那么多出的ids中的值將即作為option的 value又作為option的label。如果ids比names短那么多出的names的值會被丟掉。
當(dāng)這個select提交時所選擇的值將被提交到selectForm(name="selectForm")中的person對象(這是在 SelectForm中聲明的一個Person類型的域?qū)iT用來接收提交的值)的id屬性中(property="person.id")。
<html:select property="person.id" size="1"> <html:options property="ids" labelProperty="names"/> </html:select>
html:optionsCollection標(biāo)簽
html:optionsCollection標(biāo)簽生成多個HTML的option元素。該標(biāo)簽必須嵌在html:select標(biāo)簽中。它的功能和 html:options標(biāo)簽的相同,但是它的name與property屬性和其它標(biāo)簽的name與property屬性意義一致,理解起來比較自然。
讓我通過示例來介紹html:optionsCollection標(biāo)簽的用法。首先依據(jù)name="selectForm"和property= "persons"取到selectForm中的persons列表,然后將列表中的對象(Person類型)的id屬性作為option元素的 value值(value="id"),將列表中的對象(Person類型)的name屬性作為option元素的label值(label= "name")。
<html:select property="person.id" size="1"> <html:optionsCollection property="persons" label="name" value="id"/> </html:select>
下面是一個多選的示例,雖然示例中使用了html:options標(biāo)簽,但是html:option和html: optionsCollection也能夠用來多選。而且您還必須意識到html:option、html:options和html: optionsCollection這三個標(biāo)簽可以同時使用。代碼中的personIds是SelectForm中聲明的一個String[]類型的數(shù)組 用來接收提交的多個值。
<html:select property="personIds" multiple="true" size="2"> <html:options property="ids" labelProperty="names"/> </html:select>
html:check標(biāo)簽生成一個checkbox。這里的value值可以是true,yes或on。如果您要提交其它的值(如某種形式的標(biāo)識)應(yīng)該考慮使用html:multibox標(biāo)簽。
注意:為了正確的處理沒有選中的checkbox您必須在reset()中設(shè)置對應(yīng)的屬性為false。
下面的代碼示例了html:checkbox標(biāo)簽的用法,其中CheckboxForm中聲明了三個boolean類型的域,如下:
private boolean one = false; private boolean two = false; private boolean three = false;
<html:checkbox property="one"> One </html:checkbox> <html:checkbox property="two"> Two </html:checkbox> <html:checkbox property="three"> Three </html:checkbox>
如果選中后被提交則相應(yīng)的屬性的值為true。
html:radio標(biāo)簽生成一個radio。主要的用法有兩種,下面我們通過代碼來示例。
下面的代碼示例了html:radio標(biāo)簽的一般用法,如果被提交則選中的radio的value值將被提交到radioForm中的id中。
<html:radio property="id" value="00001"> One </html:radio> <html:radio property="id" value="00002"> Two </html:radio>
下面的代碼示例了html:radio標(biāo)簽的典型用法,其中的persons和bean:define標(biāo)簽中的一致,您可以參考bean: define標(biāo)簽。我只介紹這個<html:radio idName="person" property="id" value="id">,idName指定html:radio要使用的bean(這里為person),value="id"表示person的 id屬性將作為radio元素的value值而property="id"表示提交時選中的radio的值將被提交給radioForm中的id屬性。
<logic:notEmpty property="persons"> <logic:iterate property="persons"> <html:radio idName="person" property="id" value="id"> <bean:write property="name"/> </html:radio> </logic:iterate> </logic:notEmpty>
html:multibox標(biāo)簽生成多個checkbox。當(dāng)您要使用大量的checkbox時使用這個標(biāo)簽非常方便,可以使您避免在ActionForm中聲明大量的boolean類型的變量,帶之以一個數(shù)組就行了。
注意:為了正確的處理沒有選中的checkbox您必須在reset()中設(shè)置數(shù)組的長度為0。
下面的代碼示例了html:multibox標(biāo)簽的一般用法,如果被提交則選中的所有checkbox的value值將被提交到multiboxForm中的selectedItems中,這是一個String[]數(shù)組。
<html:multibox property="selectedItems" value="00001"/> <html:multibox property="selectedItems" value="00002"/>
下面的代碼示例了html:multibox標(biāo)簽的典型用法:
<logic:iterate property="persons"> <html:multibox property="selectedItems"> <bean:write property="id"/> </html:multibox> <bean:write property="name"/> </logic:iterate>
html:link標(biāo)簽生成一個錨點(<a>)元素。我從html:link標(biāo)簽如何構(gòu)造基本url和如何構(gòu)造query參數(shù)兩個方面來介紹這個標(biāo)簽。
構(gòu)造基本url是依據(jù)該標(biāo)簽的如下四個屬性進行的,這四個屬性一次只能出現(xiàn)一個。讓我們看看它們:
構(gòu)造query參數(shù),下面列舉了可能的形式,其中baseurl只是一個占位符:
下面我們以代碼示例來說明每一種html:link的用法,首先讓我們花點時間看看相關(guān)action中的代碼:
<!-- 下面所有代碼的數(shù)據(jù)都是在這里構(gòu)造的 --> public ActionForward execute(ActionMapping mapping,ActionForm form, HttpServletRequest request,HttpServletResponse response) { DataForm dataForm = (DataForm) form; dataForm.setParam("00001"); HashMap paramSingleMap = new HashMap(); paramSingleMap.put("p1","00001"); paramSingleMap.put("p2","00002"); paramSingleMap.put("p3","00003"); dataForm.setParamSingleMap(paramSingleMap); HashMap paramMultiMap = new HashMap(); paramMultiMap.put("p",new String[]{"00001","00002","00003"}); dataForm.setParamMultiMap(paramMultiMap); HashMap paramSMMap = new HashMap(); paramSMMap.put("p1","00001"); paramSMMap.put("p2","00002"); paramSMMap.put("p",new String[]{"00001","00002","00003"}); dataForm.setParamSMMap(paramSMMap); List<Person> persons = new ArrayList<Person>(); Person person1 = new Person(); person1.setId("00001"); person1.setName("趙辰"); Person person2 = new Person(); person2.setId("00002"); person2.setName("李為芳"); Person person3 = new Person(); person3.setId("00003"); person3.setName("王微"); persons.add(person1); persons.add(person2); persons.add(person3); dataForm.setPersons(persons); return mapping.findForward("success"); }
<!-- 這用來設(shè)置一個位置 --> <html:link linkName="top"/> <!-- 這用來定位到上面的那個位置 --> <html:link page="/link.do" anchor="top">Go Top</html:link>
<html:link page="/link.do" paramId="p" paramName="dataForm" paramProperty="param"> 單參單值 </html:link><br/> <html:link page="/link.do" property="paramSingleMap"> 多參單值 </html:link><br/> <html:link page="/link.do" property="paramMultiMap"> 單參多值 </html:link><br/> <html:link page="/link.do" property="paramSMMap"> 混合 </html:link>
下面的代碼示例了html:link標(biāo)簽的indexed屬性和indexId屬性的用法,這兩個屬性只有html:link標(biāo)簽嵌套在logic:iterate標(biāo)簽中時才可用。
<logic:iterate property="persons"> <html:link action="/link.do" paramId="person" paramName="person" paramProperty="id" indexed="true" indexId="number"> person </html:link> <br/> </logic:iterate> <!-- 下面是上面代碼的運行結(jié)果(產(chǎn)生的html) <a href="/struts-demo/link.do?person=00001&number=0">趙辰</a><br/> <a href="/struts-demo/link.do?person=00002&number=1">李為芳</a><br/> <a href="/struts-demo/link.do?person=00003&number=2">王微</a><br/> 其中的number是由indexId="number"確定的,而該參數(shù)的值為元素在集合中的位置。 -->
html:rewrite標(biāo)簽和html:link標(biāo)簽類似只是不生成錨點(<a>),而是簡單的輸出字符串。
html:errors標(biāo)簽和html:messages標(biāo)簽的功能相似,所以我們放到一起來介紹。
html:errors標(biāo)簽將由name屬性指定的ActionMessages、ActionErrors、String和String[]直接輸出到頁面中。
html:messages標(biāo)簽將用由name屬性(注意message屬性值對它的影響)指定的ActionMessages、ActionErrors、String和String[]創(chuàng)建一個新的屬性和scripting變量,使用id屬性值作為名稱。
html:errors標(biāo)簽和html:messages標(biāo)簽的property屬性是用來為errors和messages分類的。我們可以給這兩個標(biāo)簽指定property屬性,以便只顯示某一類的錯誤或消息。
在資源文件增加了如下的內(nèi)容:
# -- standard errors -- errors.header=<ul> errors.prefix=<li> errors.suffix=</li> errors.footer=</ul> error=error with none value . error1=error1 with one value is {0} . error2=error2 with two values are {0} , {1} . error3=error3 with three values are {0} , {1} , {2} . error4=error4 with four values are {0} , {1} , {2} ,{3} .
下面的代碼示例了actionErrors的構(gòu)造:
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors actionErrors = new ActionErrors(); actionErrors.add("property1", new ActionMessage("error")); actionErrors.add("property2", new ActionMessage("error1","value0")); actionErrors.add("property2", new ActionMessage("error2","value0","value1")); actionErrors.add("property3", new ActionMessage("error3","value0","value1","value2")); actionErrors.add("property3", new ActionMessage("error4","value0","value1","value2","value3")); actionErrors.add("property4", new ActionMessage("error1",new Object[]{"value0"})); actionErrors.add("property4", new ActionMessage("error2",new Object[]{"value0","value1"})); actionErrors.add("property4", new ActionMessage("error3",new Object[]{"value0","value1", "value2"})); actionErrors.add("property5", new ActionMessage("error4",new Object[]{"value0","value1", "value2","value3"})); actionErrors.add("notBundle", new ActionMessage("not a bundle key",false)); return actionErrors; }
errors標(biāo)簽代碼示例:
<html:errors/> <br/> <html:errors property="property4"/>
messages標(biāo)簽代碼示例:
<logic:messagesPresent> <ul> <html:messages > <li><bean:write /></li> </html:messages> </ul> </logic:messagesPresent> <br/> <logic:messagesPresent> <ul> <html:messages property="property4"> <li><bean:write /></li> </html:messages> </ul> </logic:messagesPresent>
html:javascript標(biāo)簽生成用于校驗的javascript腳本代碼。
下面的代碼片段示例了html:javascript標(biāo)簽的基本用法,其中formName屬性的值是在validation.xml文件的 <formset>中定義的form的名稱。有一點值得注意的是在確定<formset>時要使用合適的language屬性 值。
<html:javascript formName="dataForm"/>
html:xhtml標(biāo)簽在頁面中一出現(xiàn)就是告訴該頁的所有其它的Struts html標(biāo)簽以XHTML1.0兼容的形式輸出。這和將html:html標(biāo)簽的xhtml屬性值指定為true有些類似。如果上述情況都沒有出現(xiàn), Struts html標(biāo)簽將以html4.01兼容的形式輸出。
logic:iterate標(biāo)簽用來迭代集合,您可以使用如下方式來為這個標(biāo)簽指定其要疊代的集合:
上面所提到的集合可以是:
如果您疊代的集合中含有null的值,這時需要采取一定的措施,因為這時logic:iterate不會在page作用域中創(chuàng)建對象。一般是使用<logic:present>標(biāo)簽或<logic:notPresent>標(biāo)簽來判斷一下。
下面是logic:iterate疊代ArrayList的示例的對象引用關(guān)系和部分代碼:
圖中的persons列表是在ListAction中填充的,在這里只是簡單的加入了三個Person對象,在實際的應(yīng)用中這些數(shù)據(jù)應(yīng)該取自數(shù)據(jù)庫。具體的代碼如下:
public ActionForward execute(ActionMapping mapping,ActionForm form, HttpServletRequest request, HttpServletResponse response) { ListForm listForm = (ListForm) form; List<Person> persons = new ArrayList<Person>(); Person person1 = new Person(); person1.setId("00001"); person1.setName("趙辰"); Person person2 = new Person(); person2.setId("00002"); person2.setName("李為芳"); Person person3 = new Person(); person3.setId("00003"); person3.setName("王微"); persons.add(person1); persons.add(person2); persons.add(person3); listForm.setPersons(persons); return mapping.findForward("success"); }
標(biāo)簽輸出的結(jié)果為:
00001-->趙辰 00002-->李為芳 00003-->王微
如果指定的值出現(xiàn)該標(biāo)簽就會創(chuàng)建其標(biāo)簽體內(nèi)的內(nèi)容。該標(biāo)簽用于以下情況:
下面的代碼示例了logic:present標(biāo)簽檢查具有指定名稱User-Agent的header是否出現(xiàn):
<logic:present header="User-Agent"> 您的瀏覽器是<bean:header /> <bean:write />。<br/> </logic:present>
logic:notPresent標(biāo)簽的應(yīng)用正好和logic:present標(biāo)簽相反。
logic:messagesPresent標(biāo)簽用于以下情況:
標(biāo)簽的message屬性值為true時將以Globals.MESSAGE_KEY為key在request作用域中查找Message,其它情況下,將name的值作為key查找,如果name 沒有出現(xiàn),默認(rèn)值為Globals.ERROR_KEY。
下面的代碼示例了logic:messagesPresent標(biāo)簽的典型用法:
<logic:messagesPresent> <ul> <html:messages > <li><bean:write /></li> </html:messages> </ul> </logic:messagesPresent>
標(biāo)簽logic:messagesNotPresent的應(yīng)用正好和logic:messagesPresent的應(yīng)用相反。
logic:empty標(biāo)簽是用來判斷是否為空的。如果為空,該標(biāo)簽體中嵌入的內(nèi)容就會被處理。該標(biāo)簽用于以下情況:
下面的代碼示例了logic:empty標(biāo)簽判斷集合persons是否為空:
<logic:empty property = "persons"> <div>集合persons為空!</div> </logic:empty>
logic:notEmpty標(biāo)簽的應(yīng)用正好和logic:empty標(biāo)簽相反。
logic:match標(biāo)簽用來處理子串匹配問題。
如果指定的值匹配該標(biāo)簽就會創(chuàng)建其標(biāo)簽體內(nèi)的內(nèi)容。該標(biāo)簽用于以下情況:
下面的代碼示例了logic:match標(biāo)簽的典型用法:
<logic:present header="User-Agent"> <logic:match header="User-Agent" value="MSIE 6.0"> MS IE 6.0 </logic:match> </logic:present>
logic:notMatch標(biāo)簽的應(yīng)用正好和logic:match標(biāo)簽相反。
這里要介紹的不只是logic:equal(=)標(biāo)簽,而是要介紹一類標(biāo)簽,這類標(biāo)簽完成比較運算,包括:
該類標(biāo)簽的用法類似,我們只介紹logic:equal標(biāo)簽,其它的留給您自己去完成。
logic:equal是用來判斷是否相等的。如果相等,該標(biāo)簽體中嵌入的內(nèi)容就會被處理。該標(biāo)簽用于以下情況:
我覺得將forward和redirect這兩個動作放到一起對比著介紹更加有利于理解,基于此原因也就將logic:forward和logic:redirect這兩個標(biāo)簽也拿到這里一起介紹了。
讓我們看看這兩個動作的區(qū)別:
redirect比forward慢,因為瀏覽器要做二次請求。還有就是要注意,在第一次的請求作用域(request作用域)內(nèi)的bean對于第二次請求是不可見的。
理解了上面描述的區(qū)別也就知道了什么時候該選用logic:forward標(biāo)簽什么時候該選用logic:redirect標(biāo)簽了。logic: forward標(biāo)簽完成PageContext.forward()或HttpServletResponse.sendRedirect(),如何選擇 由控制器決定。logic:redirect標(biāo)簽完成HttpServletResponse.sendRedirect()。
在使用logic:redirect標(biāo)簽時我們可以向使用html:link一樣構(gòu)造baseurl和query參數(shù)。如果您感興趣可以參考html:link標(biāo)簽。
這篇指南的背景是Struts-1.2.9,其中的所有的代碼示例也都是在這個版本下調(diào)試通過的。