在使用SpringMVC的時(shí)候我們可以使用Spring封裝的一系列表單標(biāo)簽,這些標(biāo)簽都可以訪問到ModelMap中的內(nèi)容。下面將對這些標(biāo)簽一一介紹。
成都創(chuàng)新互聯(lián)2013年開創(chuàng)至今,先為醴陵等服務(wù)建站,醴陵等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為醴陵企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
在正式介紹SpringMVC的表單標(biāo)簽之前,我們需要先在JSP中聲明使用的標(biāo)簽,具體做法是在JSP文件的頂部加入以下指令:
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
1.1、form標(biāo)簽
使用Spring的form標(biāo)簽主要有兩個(gè)作用,第一是它會(huì)自動(dòng)的綁定來自Model中的一個(gè)屬性值到當(dāng)前form對應(yīng)的實(shí)體對象,默認(rèn)是command屬性,這樣我們就可以在form表單體里面方便的使用該對象的屬性了;第二是它支持我們在提交表單的時(shí)候使用除GET和POST之外的其他方法進(jìn)行提交,包括DELETE和PUT等。
1.1.1 支持綁定表單對象
我們先來看如下使用form標(biāo)簽的一個(gè)示例:
<form:form action="formTag/form.do" method="post"> <table> <tr> <td>Name:</td><td><form:input path="name"/></td> </tr> <tr> <td>Age:</td><td><form:input path="age"/></td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
這個(gè)時(shí)候如果Model中存在一個(gè)屬性名稱為command的javaBean,而且該javaBean擁有屬性name和age的時(shí)候,在渲染上面的代碼時(shí)就會(huì)取command的對應(yīng)屬性值賦給對應(yīng)標(biāo)簽的值。如在上面的代碼中,假設(shè)Model中存在一個(gè)屬性名稱為command的javaBean,且它的name和age屬性分別為“Zhangsan”和“36”時(shí),那么它在渲染時(shí)就會(huì)生成如下一段代碼:
<form id="command" action="formTag/form.do" method="post"> <table> <tr> <td>Name:</td><td><input id="name" name="name" type="text" value="ZhangSan"/></td> </tr> <tr> <td>Age:</td><td><input id="age" name="age" type="text" value="36"/></td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form>
從上面生成的代碼中,我們可以看出,當(dāng)沒有指定form標(biāo)簽的id時(shí)它會(huì)自動(dòng)獲取該form標(biāo)簽綁定的Model中對應(yīng)屬性名稱作為id,而對于input標(biāo)簽在沒有指定id的情況下它會(huì)自動(dòng)獲取path指定的屬性作為id和name。
我們指定form默認(rèn)自動(dòng)綁定的是Model的command屬性值,那么當(dāng)我的form對象對應(yīng)的屬性名稱不是command的時(shí)候,應(yīng)該怎么辦呢?對于這種情況,Spring給我們提供了一個(gè)commandName屬性,我們可以通過該屬性來指定我們將使用Model中的哪個(gè)屬性作為form需要綁定的command對象。除了commandName屬性外,指定modelAttribute屬性也可以達(dá)到相同的效果。這里假設(shè)上面代碼中我們存放在Model中的是user對象而不是默認(rèn)的command對象,那么我們的代碼就可以如下定義了:
<form:form action="formTag/form.do" method="post" commandName="user"> <table> <tr> <td>Name:</td><td><form:input path="name"/></td> </tr> <tr> <td>Age:</td><td><form:input path="age"/></td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
1.1.2 支持全部的Http請求方法
<form:form action="formTag/form.do" method="delete" modelAttribute="user"> <table> <tr> <td>Name:</td><td><form:input path="name"/></td> </tr> <tr> <td>Age:</td><td><form:input path="age"/></td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
在上面代碼中我們設(shè)定了該form的提交方法是delete,這樣在后臺(tái)我們就可以給對應(yīng)的請求方法的RequestMapping加上method為RequestMethod.DELETE的限制。我們來看一下上面的代碼在進(jìn)行渲染的時(shí)候會(huì)生成怎樣的Html代碼,其生成的代碼如下所示:
<form id="user" action="formTag/form.do" method="post"> <input type="hidden" name="_method" value="delete"/> <table> <tr> <td>Name:</td><td><input id="name" name="name" type="text" value="ZhangSan"/></td> </tr> <tr> <td>Age:</td><td><input id="age" name="age" type="text" value="36"/></td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form>
從它生成的代碼我們可以看出,Spring在實(shí)現(xiàn)除GET和POST之外的請求方法時(shí),還是使用的POST方法進(jìn)行請求,然后給表單加上了一個(gè)隱藏域,用以表示真正的請求方法,這個(gè)隱藏域的名稱默認(rèn)是“_method”。上面這樣定義之后是不是就意味著我們可以以delete方式訪問到“formTag/form.do”了呢?答案是不行的。這樣定義我們只是多加了一個(gè)用以表示請求方法的隱藏域而已,實(shí)際的請求方式還是POST。Spring為我們提供了一個(gè)Filter——HiddenHttpMethodFilter,通過這個(gè)Filter我們可以把以POST方式傳遞過來的表示實(shí)際請求方式的參數(shù)轉(zhuǎn)換為對應(yīng)的真正的Http請求方法。所以這個(gè)時(shí)候我們還需要在web.xml中加上如下代碼:
<filter> <filter-name>hiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>hiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
注意:HiddenHttpMethodFilter只能對以POST方式進(jìn)行傳遞的表示請求方式的隱藏域轉(zhuǎn)換為真正的Http請求方式。當(dāng)我們直接在form:form標(biāo)簽的method中使用除GET和POST方法以外的其他方法時(shí),Spring會(huì)自動(dòng)生成以POST方式進(jìn)行傳遞的表單以及對應(yīng)的隱藏域。所以當(dāng)我們需要手動(dòng)的設(shè)置表示請求方法的隱藏域時(shí),我們就需要指定表單的請求方式為POST,為GET將不會(huì)生效。
<form:form action="formTag/form.do" method="post" modelAttribute="user"> <input type="hidden" name="_method" value="head"/> <table> <tr> <td>Name:</td><td><form:input path="name"/></td> </tr> <tr> <td>Age:</td><td><form:input path="age"/></td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
上面代碼就是一個(gè)手動(dòng)定義請求方式的隱藏域的示例。這里表示請求方式的隱藏域的名稱默認(rèn)是“_method”,如果不想使用這個(gè)默認(rèn)值的話,我們也可以通過form:form標(biāo)簽的methodParam屬性來指定。如下面這個(gè)示例:
<form:form action="formTag/form.do" method="post" methodParam="requestMethod" modelAttribute="user"> <input type="hidden" name="requestMethod" value="head"/> <table> <tr> <td>Name:</td><td><form:input path="name"/></td> </tr> <tr> <td>Age:</td><td><form:input path="age"/></td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
同時(shí)我們也要告訴HiddenHttpMethodFilter我們是使用哪個(gè)表單參數(shù)作為methodParam,所以我們需要在配置HiddenHttpMethodFilter的時(shí)候指明methodParam對應(yīng)的值。
<filter> <filter-name>hiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> <init-param> <param-name>methodParam</param-name> <param-value>requestMethod</param-value> </init-param> </filter> <filter-mapping> <filter-name>hiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
另外需要注意的是在有Multipart請求處理的時(shí)候HiddenHttpMethodFilter需要在Multipart處理之后執(zhí)行,因?yàn)樵谔幚鞰ultipart時(shí)需要從POST請求體中獲取參數(shù)。所以我們通常會(huì)在HiddenHttpMethodFilter之前設(shè)立一個(gè)MultipartFilter。MultipartFilter默認(rèn)會(huì)去尋找一個(gè)名稱為filterMultipartResolver的MultipartResolver bean對象來對當(dāng)前的請求進(jìn)行封裝。所以當(dāng)你定義的MultipartResolver的名稱不為filterMultipartResolver的時(shí)候就需要在定義MultipartFilter的時(shí)候通過參數(shù)multipartResolverBeanName來指定。
<filter> <filter-name>multipartFilter</filter-name> <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class> <init-param> <param-name>multipartResolverBeanName</param-name> <param-value>multipartResolver</param-value> </init-param> </filter> <filter-mapping> <filter-name>multipartFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>hiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> <init-param> <param-name>methodParam</param-name> <param-value>requestMethod</param-value> </init-param> </filter> <filter-mapping> <filter-name>hiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
1.2 、input標(biāo)簽
SpringMVC的input標(biāo)簽會(huì)被渲染為一個(gè)type為text的普通Html input標(biāo)簽。使用SpringMVC的input標(biāo)簽的唯一作用就是它能綁定表單數(shù)據(jù)。SpringMVC表單標(biāo)簽最大的好處就是它支持?jǐn)?shù)據(jù)綁定,當(dāng)我們的表單標(biāo)簽不需要綁定的數(shù)據(jù)的時(shí)候,我們應(yīng)該使用普通的Html標(biāo)簽。關(guān)于input標(biāo)簽綁定表單數(shù)據(jù)的方法已經(jīng)在介紹form標(biāo)簽的時(shí)候順帶介紹過了,這里就不再過多的贅述了。
<form:form action="formTag/form.do" method="head" modelAttribute="user" methodParam="requestMethod"> <table> <tr> <td>Name:</td><td><form:input path="name"/></td> </tr> <tr> <td>Age:</td><td><form:input path="age"/></td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
1.3 、hidden標(biāo)簽
hidden標(biāo)簽會(huì)被渲染為一個(gè)type為hidden的普通Html input標(biāo)簽。用法跟input標(biāo)簽一樣,也能綁定表單數(shù)據(jù),只是它生成的是一個(gè)隱藏域。
1.4 、checkbox標(biāo)簽
checkbox標(biāo)簽會(huì)被渲染為一個(gè)type為checkbox的普通HTML input標(biāo)簽。checkbox標(biāo)簽也是支持綁定數(shù)據(jù)的。我們知道checkbox就是一個(gè)復(fù)選框,有選中和不選中兩種狀態(tài),那么我們在使用checkbox標(biāo)簽的時(shí)候是如何來設(shè)定它的狀態(tài)的呢?checkbox標(biāo)簽的選中與否狀態(tài)是根據(jù)它綁定的值來判斷的。
1.4.1 綁定boolean數(shù)據(jù)
當(dāng)checkbox綁定的是一個(gè)boolean數(shù)據(jù)的時(shí)候,那么checkbox的狀態(tài)跟該boolean數(shù)據(jù)的狀態(tài)是一樣的,即true對應(yīng)選中,false對應(yīng)不選中。
<form:form action="formTag/form.do" method="post" commandName="user"> <table> <tr> <td>Male:</td><td><form:checkbox path="male"/></td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
看上面這段代碼,這個(gè)時(shí)候假設(shè)我們在渲染該視圖之前往ModelMap中添加了一個(gè)user屬性,并且該user對象有一個(gè)類型為boolean的屬性male,那么這個(gè)時(shí)候如果male屬性為true則Male那一欄的復(fù)選框?qū)?huì)被選中。
1.4.2 綁定列表數(shù)據(jù)
這里的列表數(shù)據(jù)包括數(shù)組、List和Set。下面將以List為例講一下checkbox是如何根據(jù)綁定的列表數(shù)據(jù)來設(shè)定選中狀態(tài)的。現(xiàn)在假設(shè)有一個(gè)類User,其有一個(gè)類型為List的屬性roles,如下所示:
public class User { private List<String> roles; public List<String> getRoles() { return roles; } public void setRoles(List<String> roles) { this.roles = roles; } }
那么當(dāng)我們需要展現(xiàn)該User是否擁有某一個(gè)Role的時(shí)候,我們可以使用checkbox標(biāo)簽來綁定roles數(shù)據(jù)進(jìn)行展現(xiàn)。當(dāng)checkbox標(biāo)簽的value在我們綁定的列表數(shù)據(jù)中存在的時(shí)候該checkbox將為選中狀態(tài)。來看下面一段代碼:
<form:form action="formTag/form.do" method="post" commandName="user"> <table> <tr> <td>Roles:</td> <td> <form:checkbox path="roles" value="role1"/>Role1<br/> <form:checkbox path="roles" value="role2"/>Role2<br/> <form:checkbox path="roles" value="role3"/>Role3 </td> </tr> </table> </form:form>
就上面代碼而言就是當(dāng)User擁有role1的時(shí)候?qū)?yīng)的<form:checkbox path="roles" value="role1"/>就會(huì)為選中狀態(tài),也就是說roles列表中包含role1的時(shí)候該checkbox就會(huì)為選中狀態(tài)。
1.4.3 綁定一個(gè)Object數(shù)據(jù)
checkbox還支持綁定數(shù)據(jù)類型為Object的數(shù)據(jù),這種情況下Spring會(huì)拿所綁定對象數(shù)據(jù)的toString結(jié)果跟當(dāng)前checkbox的value進(jìn)行比較,如果能夠進(jìn)行匹配則該checkbox將為選中狀態(tài)。看這樣一個(gè)例子,有一個(gè)User類代碼如下:
public class User { private Blog blog; public Blog getBlog() { return blog; } public void setBlog(Blog blog) { this.blog = blog; } }
Blog類的代碼如下:
public class Blog { public String toString() { return "HelloWorld"; } }
我們可以看到Blog類的toString方法已經(jīng)被寫死為“HelloWorld”了。這個(gè)時(shí)候假設(shè)我們往ModelMap中放了一個(gè)user對象,而且給該user對象設(shè)定了一個(gè)blog屬性,那么當(dāng)我們使用該ModelMap對象渲染如下視圖代碼時(shí),checkbox標(biāo)簽的選中狀態(tài)是怎樣的呢?
根據(jù)前面描述的當(dāng)checkbox標(biāo)簽綁定的是一個(gè)Object對象的時(shí)候我們會(huì)拿該Object對象的toString和checkbox的value值進(jìn)行比較,如果匹配則當(dāng)前checkbox為選中狀態(tài),我們知道這里的checkbox將為選中狀態(tài)。
<form:form action="formTag/form.do" method="post" commandName="user"> <table> <tr> <td>HelloWorld:</td> <td> <form:checkbox path="blog" value="HelloWorld"/> </td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
1.5、Checkboxes標(biāo)簽
相對于一個(gè)checkbox標(biāo)簽只能生成一個(gè)對應(yīng)的復(fù)選框而言,一個(gè)checkboxes標(biāo)簽將根據(jù)其綁定的數(shù)據(jù)生成N個(gè)復(fù)選框。checkboxes綁定的數(shù)據(jù)可以是數(shù)組、集合和Map。在使用checkboxes時(shí)我們有兩個(gè)屬性是必須指定的,一個(gè)是path,另一個(gè)是items。Items表示當(dāng)前要用來展現(xiàn)的項(xiàng)有哪些,而path所綁定的表單對象的屬性表示當(dāng)前表單對象擁有的項(xiàng),即在items所展現(xiàn)的所有項(xiàng)中表單對象擁有的項(xiàng)會(huì)被設(shè)定為選中狀態(tài)。先來看以下一段代碼:
<form:form action="formTag/form.do" method="post" commandName="user"> <table> <tr> <td>Roles:</td> <td> <form:checkboxes path="roles" items="${roleList}"/> </td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
上面的JSP視圖對應(yīng)著如下的處理器方法:
@RequestMapping(value="form", method=RequestMethod.GET) public String formTag(Map<String, Object> map) { User user = new User(); List<String> roles = new ArrayList<String>(); roles.add("role1"); roles.add("role3"); user.setRoles(roles); List<String> roleList = new ArrayList<String>(); roleList.add("role1"); roleList.add("role2"); roleList.add("role3"); map.put("user", user); map.put("roleList", roleList); return "formTag/form"; }
從以上代碼中我們可以看到我們放在ModelMap中的roleList對象有三個(gè)元素,分別是role1、role2和role3,而我們的表單對象User的roles屬性只擁有兩個(gè)元素,分別是role1和role3,,所以當(dāng)我們訪問該處理器方法返回如上所示的視圖頁面時(shí),我們要展現(xiàn)的復(fù)選框項(xiàng)是roleList,也就是role1、role2和role3,而我們表單對象只擁有role1和role3,所以在頁面進(jìn)行渲染的時(shí)候會(huì)展示3個(gè)復(fù)選框項(xiàng),但只有role1和role3會(huì)被設(shè)定為選中狀態(tài)。
上面介紹的這種情況是使用List作為展現(xiàn)復(fù)選框項(xiàng)的數(shù)據(jù)源,這種情況我們已經(jīng)看到了它所呈現(xiàn)出來的標(biāo)簽Label和它的值是一樣的。使用Array和Set作為數(shù)據(jù)源也是這種情況。那么如果要讓checkboxes呈現(xiàn)出來的Label和實(shí)際上送的value不同的話應(yīng)該怎么做呢?這個(gè)時(shí)候我們就可以使用Map作為數(shù)據(jù)源了。使用Map作為checkboxes的items屬性的數(shù)據(jù)源時(shí)Key將作為真正的復(fù)選框的value,而Map的value將作為Label進(jìn)行展示。當(dāng)使用Map作為checkboxes的items屬性的數(shù)據(jù)源時(shí)我們綁定的表單對象屬性的類型可以是Array、集合和Map,這種情況就是判斷items Map中是否含有對應(yīng)的key來決定當(dāng)前的復(fù)選框是否處于選中狀態(tài)。我們來看以下一個(gè)處理器方法以及其對應(yīng)的視圖代碼。
處理器方法:
@RequestMapping(value="form", method=RequestMethod.GET) public String formTag(Map<String, Object> map) { User user = new User(); List<String> roles = new ArrayList<String>(); roles.add("role1"); roles.add("role3"); user.setRoles(roles); Map<String, String> roleMap = new HashMap<String, String>(); roleMap.put("role1", "角色1"); roleMap.put("role2", "角色2"); roleMap.put("role3", "角色3"); map.put("user", user); map.put("roleMap", roleMap); return "formTag/form"; }
對應(yīng)的視圖代碼:
<form:form action="formTag/form.do" method="post" commandName="user"> <table> <tr> <td>Roles:</td> <td> <form:checkboxes path="roles" items="${roleMap}"/> </td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
這個(gè)時(shí)候我們知道會(huì)呈現(xiàn)出3個(gè)復(fù)選框,而checkboxes綁定的表單對象user的roles屬性是一個(gè)集合對象,其包含的兩個(gè)元素都能在checkboxes的items數(shù)據(jù)源中找到對應(yīng)的Key,所以以這兩個(gè)元素為value的checkbox將處于選中狀態(tài)。效果如下:
當(dāng)我們使用Array或者集合作為數(shù)據(jù)源,且里面的元素都是一個(gè)一個(gè)POJO時(shí),我們還可以使用checkboxes標(biāo)簽的itemLabel和itemValue屬性來表示使用數(shù)組或者集合中元素對象的哪一個(gè)屬性作為需要呈現(xiàn)的單選框的label和value。
1.6、radiobutton標(biāo)簽
radiobutton標(biāo)簽會(huì)被渲染為一個(gè)type為radio的普通HTML input標(biāo)簽。radiobutton標(biāo)簽也是可以綁定數(shù)據(jù)的。以下是一個(gè)radiobutton的簡單應(yīng)用示例:
<form:form action="formTag/form.do" method="post" commandName="user"> <table> <tr> <td>性別:</td> <td> <form:radiobutton path="sex" value="1"/>男 <form:radiobutton path="sex" value="0"/>女 </td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
在上面代碼中我們的radiobutton標(biāo)簽都是綁定了表單對象user的sex屬性,當(dāng)sex為1的時(shí)候就代表性別為男,上面性別為男的那一行就會(huì)被選中,當(dāng)sex為0的時(shí)候就代表性別為女,上面性別為女的那一行就會(huì)被選中。
1.7、radiobuttons標(biāo)簽
radiobuttons標(biāo)簽跟radiobutton標(biāo)簽的區(qū)別如同checkbox標(biāo)簽對checkboxes標(biāo)簽的區(qū)別。使用radiobuttons標(biāo)簽的時(shí)候?qū)⑸啥鄠€(gè)單選按鈕。使用radiobuttons有兩個(gè)屬性也是我們必須指定的,一個(gè)是path屬性,表示綁定的表單對象對應(yīng)的屬性,另一個(gè)是items屬性,表示用于生成單選按鈕的數(shù)據(jù)源。跟checkboxes一樣,radiobuttons的items屬性和path屬性都可以是Array、集合或者是Map?,F(xiàn)在我們假設(shè)user在籃球、足球、乒乓球、羽毛球和排球這5種運(yùn)動(dòng)中選擇一種作為自己最喜歡的球類運(yùn)動(dòng)。處理器方法和返回的對應(yīng)的視圖代碼如下:
@RequestMapping(value="form", method=RequestMethod.GET) public String formTag(Map<String, Object> map) { User user = new User(); user.setFavoriteBall(4);//設(shè)置我最喜愛的球類運(yùn)動(dòng)是4羽毛球 Map<Integer, String> ballMap = new HashMap<Integer, String>(); ballMap.put(1, "籃球"); ballMap.put(2, "足球"); ballMap.put(3, "乒乓球"); ballMap.put(4, "羽毛球"); ballMap.put(5, "排球"); map.put("user", user); map.put("ballMap", ballMap); return "formTag/form"; }
<form:form action="formTag/form.do" method="post" commandName="user"> <table> <tr> <td>最喜歡的球類:</td> <td> <form:radiobuttons path="favoriteBall" items="${ballMap}" delimiter=" "/> </td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
在上述代碼中我們可以看到我們使用了radiobuttons的delimiter屬性,該屬性表示進(jìn)行展示的radiobutton之間的分隔符。這里用的是一個(gè)空格。結(jié)果頁面如下所示:
1.8、password標(biāo)簽
password標(biāo)簽將會(huì)被渲染為一個(gè)type為password的普通HTML input標(biāo)簽。
1.9、select標(biāo)簽
select標(biāo)簽將會(huì)被渲染為一個(gè)普通的HTML select標(biāo)簽。這里還拿前面的user最喜歡的球類運(yùn)動(dòng)來做示例,有如下這樣一個(gè)處理器方法和對應(yīng)的視圖頁面:
@RequestMapping(value="form", method=RequestMethod.GET) public String formTag(Map<String, Object> map) { User user = new User(); user.setFavoriteBall(4);//設(shè)置我最喜愛的球類運(yùn)動(dòng)是4羽毛球 Map<Integer, String> ballMap = new HashMap<Integer, String>(); ballMap.put(1, "籃球"); ballMap.put(2, "足球"); ballMap.put(3, "乒乓球"); ballMap.put(4, "羽毛球"); ballMap.put(5, "排球"); map.put("user", user); map.put("ballMap", ballMap); return "formTag/form"; }
<form:form action="formTag/form.do" method="post" commandName="user"> <table> <tr> <td>最喜歡的運(yùn)動(dòng):</td> <td> <form:select path="favoriteBall" items="${ballMap}"/> </td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
這個(gè)時(shí)候會(huì)渲染出如下結(jié)果:
從上面示例我們可以看出,我們通過items屬性給select標(biāo)簽指定了一個(gè)數(shù)據(jù)源,并且綁定了表單對象user的favoriteBall屬性。Items屬性是用于指定當(dāng)前select的所有可選項(xiàng)的,但是它對于select標(biāo)簽而言不是必須的,因?yàn)槲覀冞€可以手動(dòng)的在select標(biāo)簽中間加上option標(biāo)簽來指定select可選的option。Select標(biāo)簽支持的items屬性的數(shù)據(jù)類型可以是Array、Collection和Map,當(dāng)數(shù)據(jù)類型為Array或Collection時(shí)且其中的元素為一個(gè)POJO時(shí),我們可以通過屬性itemLabel和itemValue來指定將用于呈現(xiàn)的option Label和Value,其他情況下Array和Collection數(shù)據(jù)源中的元素將既作為可選項(xiàng)option的value又作為它的Label。當(dāng)items的數(shù)據(jù)類型為Map時(shí),Map的key將作為可選項(xiàng)option的value,而Map的value將作為option的Label標(biāo)簽。
1.10、 option標(biāo)簽
option標(biāo)簽會(huì)被渲染為一個(gè)普通的HTML option標(biāo)簽。當(dāng)一個(gè)SpringMVC select標(biāo)簽沒有通過items屬性指定自己的數(shù)據(jù)源的時(shí)候,我們就可以在select標(biāo)簽中通過普通HTML option標(biāo)簽或者SpringMVC option標(biāo)簽來指定可以選擇的項(xiàng)。
<form:form action="formTag/form.do" method="post" commandName="user"> <table> <tr> <td>最喜歡的運(yùn)動(dòng):</td> <td> <form:select path="favoriteBall"> <option>請選擇</option> <form:option value="1">籃球</form:option> <option value="4">羽毛球</option> </form:select> </td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
我們可以看到在上面代碼中我們是沒有指定select標(biāo)簽的數(shù)據(jù)源的,而是通過在select標(biāo)簽體里面指定普通HTML option標(biāo)簽和SpringMVC option標(biāo)簽來指定可選項(xiàng)。其渲染的效果如下:
這個(gè)時(shí)候你可能會(huì)有兩個(gè)疑問:
l 如果我在使用select標(biāo)簽的時(shí)候通過items屬性指定了其數(shù)據(jù)源,同時(shí)又在其標(biāo)簽體里面使用了option標(biāo)簽,那么這個(gè)時(shí)候會(huì)渲染出什么樣的效果呢?是兩種形式有一個(gè)優(yōu)先級(jí)呢,還是會(huì)兩種共存呢?
l 從上面代碼產(chǎn)生的效果來看SpringMVC option標(biāo)簽跟普通的HTML option標(biāo)簽的效果無異,那為什么還要引進(jìn)一個(gè)SpringMVC option標(biāo)簽?zāi)兀?/p>
先來解釋第一個(gè)問題,我們把上面的視圖代碼改為如下形式:
<form:form action="formTag/form.do" method="post" commandName="user"> <table> <tr> <td>最喜歡的運(yùn)動(dòng):</td> <td> <form:select path="favoriteBall" items="${ballMap}"> <option>請選擇</option> <form:option value="1">籃球</form:option> <option value="4">羽毛球</option> </form:select> </td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
從上述代碼中我們可以看出來我們就是給select標(biāo)簽加了一個(gè)items屬性,然后指定其數(shù)據(jù)源為當(dāng)前pageContext的ballMap屬性。此時(shí),將渲染出如下效果:
答案很明顯,當(dāng)select標(biāo)簽指定了items屬性的時(shí)候,它會(huì)忽略其標(biāo)簽體的內(nèi)容,而使用items指定的內(nèi)容來渲染出可選項(xiàng)。
對于第二個(gè)問題,我們把視圖代碼改為如下形式:
<form:form action="formTag/form.do" method="post" commandName="user"> <table> <tr> <td>最喜歡的運(yùn)動(dòng):</td> <td> <form:select path="favoriteBall"> <option>請選擇</option> <form:option value="1">籃球</form:option> <option value="4">羽毛球-A</option> <form:option value="4">羽毛球-B</form:option> </form:select> </td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
我們可以看到,在上面代碼中,我們定義了一個(gè)select標(biāo)簽,其綁定了當(dāng)前表單對象user的favoriteBall屬性,而且我們沒有給該select指定items數(shù)據(jù)源。值得注意的是在該select標(biāo)簽體中我們通過普通HTML option和SpringMVC option標(biāo)簽定義了兩個(gè)value均為4的option元素,而且我們也知道當(dāng)前表單對象user的favoriteBall屬性的值是4。接著我們來看一下上面代碼渲染出的效果:
接著我們把上述代碼中以SpringMVC option標(biāo)簽定義的option給刪除,再看一下其渲染出的效果如下:
由此我們可以看出SpringMVC option標(biāo)簽和普通HTML option標(biāo)簽的區(qū)別就在于普通HTML option標(biāo)簽不具備數(shù)據(jù)綁定功能,而SpringMVC option標(biāo)簽具有數(shù)據(jù)綁定功能,它能把當(dāng)前綁定的表單對象的屬性對應(yīng)的值對應(yīng)的option置為選中狀態(tài)。
1.11、options標(biāo)簽
使用options標(biāo)簽的時(shí)候需要我們指定其items屬性,它會(huì)根據(jù)其items屬性生成一系列的普通HTML option標(biāo)簽。這里的items屬性的可取數(shù)據(jù)類型及其對應(yīng)的渲染規(guī)則跟select的items屬性是一樣的。
<form:form action="formTag/form.do" method="post" commandName="user"> <table> <tr> <td>最喜歡的運(yùn)動(dòng):</td> <td> <form:select path="favoriteBall"> <option>請選擇</option> <form:options items="${ballMap}"/> </form:select> </td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
上面代碼將渲染出如下效果:
1.12、textarea標(biāo)簽
SpringMVC textarea標(biāo)簽將被渲染為普通HTML textarea標(biāo)簽。簡單示例如下:
<form:form action="formTag/form.do" method="post" commandName="user"> <table> <tr> <td>自我介紹:</td> <td> <form:textarea path="introduction" cols="20" rows="10"/> </td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
1.13、errors標(biāo)簽
SpringMVC errors標(biāo)簽是對應(yīng)于SpringMVC的Errors對象的。它的作用就是用于展現(xiàn)Errors對象中包含的錯(cuò)誤信息的。我們利用errors標(biāo)簽來展現(xiàn)Errors的時(shí)候是通過errors標(biāo)簽的path屬性來綁定一個(gè)錯(cuò)誤信息的。我們可以通過path屬性來展現(xiàn)兩種類型的錯(cuò)誤信息。
l 所有的錯(cuò)誤信息,這個(gè)時(shí)候path的值應(yīng)該置為“*”
l 當(dāng)前對象的某一個(gè)域的錯(cuò)誤信息,這個(gè)時(shí)候path的值應(yīng)為所需展現(xiàn)的域的名稱
看下面這樣一個(gè)例子:
定義了一個(gè)UserValidator對象,專門用來對User對象進(jìn)行驗(yàn)證,其代碼如下:
import org.springframework.validation.Errors; import org.springframework.validation.ValidationUtils; import org.springframework.validation.Validator; public class UserValidator implements Validator { @Override public boolean supports(Class<?> clazz) { // TODO Auto-generated method stub return User.class.equals(clazz); } @Override public void validate(Object target, Errors errors) { // TODO Auto-generated method stub ValidationUtils.rejectIfEmpty(errors, "name", null, "Name Is Empty"); ValidationUtils.rejectIfEmpty(errors, "username", null, "Username Is Empty."); } }
然后我們有這樣一個(gè)控制器類:
@Controller @RequestMapping("formTag") public class FormTagController { @RequestMapping(value="form", method=RequestMethod.GET) public String formTag(Map<String, Object> map) { User user = new User(); map.put("user", user); return "formTag/form"; } @InitBinder public void initBinder(DataBinder binder) { binder.setValidator(new UserValidator()); } @RequestMapping(value="form", method=RequestMethod.POST) public String form(@Valid User user, Errors errors) { if (errors.hasFieldErrors()) return "formTag/form"; return "formTag/submit"; } }
我們可以看到我們在上述控制器類中通過DataBinder對象給該類設(shè)定了一個(gè)用于驗(yàn)證的UserValidator,這樣當(dāng)我們請求該控制器的時(shí)候UserValidator將生效。
我們有如下這樣一段表單代碼:
<form:form action="formTag/form.do" method="post" commandName="user"> <table border="1px" bordercolor="blue"> <tr align="center"> <td width="100">姓名:</td> <td width="150"><form:input path="name"/></td> </tr> <tr align="center"> <td>用戶名:</td> <td><form:input path="username"/></td> </tr> <tr> <td>所有錯(cuò)誤信息:</td> <td><form:errors path="*"/></td> </tr> <tr> <td>Name的錯(cuò)誤信息:</td> <td><form:errors path="name"/></td> </tr> <tr align="center"> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
當(dāng)我們提交上面的表單的時(shí)候會(huì)往Errors中注入兩個(gè)錯(cuò)誤信息,展示的頁面信息將如下所示:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
當(dāng)前文章:SpringMVC表單標(biāo)簽使用詳解
文章路徑:http://jinyejixie.com/article14/ppspge.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、ChatGPT、App開發(fā)、移動(dòng)網(wǎng)站建設(shè)、全網(wǎng)營銷推廣、網(wǎng)站營銷
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)