在使用springmvc的時候我們可以使用spring封裝的一系列表單標簽,這些標簽都可以訪問到modelmap中的內容。下面將對這些標簽一一介紹。
在正式介紹springmvc的表單標簽之前,我們需要先在jsp中聲明使用的標簽,具體做法是在jsp文件的頂部加入以下指令:
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
1.1、form標簽
使用spring的form標簽主要有兩個作用,第一是它會自動的綁定來自model中的一個屬性值到當前form對應的實體對象,默認是command屬性,這樣我們就可以在form表單體里面方便的使用該對象的屬性了;第二是它支持我們在提交表單的時候使用除get和post之外的其他方法進行提交,包括delete和put等。
1.1.1 支持綁定表單對象
我們先來看如下使用form標簽的一個示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<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> |
這個時候如果model中存在一個屬性名稱為command的javabean,而且該javabean擁有屬性name和age的時候,在渲染上面的代碼時就會取command的對應屬性值賦給對應標簽的值。如在上面的代碼中,假設model中存在一個屬性名稱為command的javabean,且它的name和age屬性分別為“zhangsan”和“36”時,那么它在渲染時就會生成如下一段代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<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> |
從上面生成的代碼中,我們可以看出,當沒有指定form標簽的id時它會自動獲取該form標簽綁定的model中對應屬性名稱作為id,而對于input標簽在沒有指定id的情況下它會自動獲取path指定的屬性作為id和name。
我們指定form默認自動綁定的是model的command屬性值,那么當我的form對象對應的屬性名稱不是command的時候,應該怎么辦呢?對于這種情況,spring給我們提供了一個commandname屬性,我們可以通過該屬性來指定我們將使用model中的哪個屬性作為form需要綁定的command對象。除了commandname屬性外,指定modelattribute屬性也可以達到相同的效果。這里假設上面代碼中我們存放在model中的是user對象而不是默認的command對象,那么我們的代碼就可以如下定義了:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<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請求方法
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<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> |
在上面代碼中我們設定了該form的提交方法是delete,這樣在后臺我們就可以給對應的請求方法的requestmapping加上method為requestmethod.delete的限制。我們來看一下上面的代碼在進行渲染的時候會生成怎樣的html代碼,其生成的代碼如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<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在實現除get和post之外的請求方法時,還是使用的post方法進行請求,然后給表單加上了一個隱藏域,用以表示真正的請求方法,這個隱藏域的名稱默認是“_method”。上面這樣定義之后是不是就意味著我們可以以delete方式訪問到“formtag/form.do”了呢?答案是不行的。這樣定義我們只是多加了一個用以表示請求方法的隱藏域而已,實際的請求方式還是post。spring為我們提供了一個filter——hiddenhttpmethodfilter,通過這個filter我們可以把以post方式傳遞過來的表示實際請求方式的參數轉換為對應的真正的http請求方法。所以這個時候我們還需要在web.xml中加上如下代碼:
1
2
3
4
5
6
7
8
|
<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方式進行傳遞的表示請求方式的隱藏域轉換為真正的http請求方式。當我們直接在form:form標簽的method中使用除get和post方法以外的其他方法時,spring會自動生成以post方式進行傳遞的表單以及對應的隱藏域。所以當我們需要手動的設置表示請求方法的隱藏域時,我們就需要指定表單的請求方式為post,為get將不會生效。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<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> |
上面代碼就是一個手動定義請求方式的隱藏域的示例。這里表示請求方式的隱藏域的名稱默認是“_method”,如果不想使用這個默認值的話,我們也可以通過form:form標簽的methodparam屬性來指定。如下面這個示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<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> |
同時我們也要告訴hiddenhttpmethodfilter我們是使用哪個表單參數作為methodparam,所以我們需要在配置hiddenhttpmethodfilter的時候指明methodparam對應的值。
1
2
3
4
5
6
7
8
9
10
11
12
|
<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請求處理的時候hiddenhttpmethodfilter需要在multipart處理之后執行,因為在處理multipart時需要從post請求體中獲取參數。所以我們通常會在hiddenhttpmethodfilter之前設立一個multipartfilter。multipartfilter默認會去尋找一個名稱為filtermultipartresolver的multipartresolver bean對象來對當前的請求進行封裝。所以當你定義的multipartresolver的名稱不為filtermultipartresolver的時候就需要在定義multipartfilter的時候通過參數multipartresolverbeanname來指定。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<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標簽
springmvc的input標簽會被渲染為一個type為text的普通html input標簽。使用springmvc的input標簽的唯一作用就是它能綁定表單數據。springmvc表單標簽最大的好處就是它支持數據綁定,當我們的表單標簽不需要綁定的數據的時候,我們應該使用普通的html標簽。關于input標簽綁定表單數據的方法已經在介紹form標簽的時候順帶介紹過了,這里就不再過多的贅述了。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<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標簽
hidden標簽會被渲染為一個type為hidden的普通html input標簽。用法跟input標簽一樣,也能綁定表單數據,只是它生成的是一個隱藏域。
1.4 、checkbox標簽
checkbox標簽會被渲染為一個type為checkbox的普通html input標簽。checkbox標簽也是支持綁定數據的。我們知道checkbox就是一個復選框,有選中和不選中兩種狀態,那么我們在使用checkbox標簽的時候是如何來設定它的狀態的呢?checkbox標簽的選中與否狀態是根據它綁定的值來判斷的。
1.4.1 綁定boolean數據
當checkbox綁定的是一個boolean數據的時候,那么checkbox的狀態跟該boolean數據的狀態是一樣的,即true對應選中,false對應不選中。
1
2
3
4
5
6
7
8
9
10
|
<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> |
看上面這段代碼,這個時候假設我們在渲染該視圖之前往modelmap中添加了一個user屬性,并且該user對象有一個類型為boolean的屬性male,那么這個時候如果male屬性為true則male那一欄的復選框將會被選中。
1.4.2 綁定列表數據
這里的列表數據包括數組、list和set。下面將以list為例講一下checkbox是如何根據綁定的列表數據來設定選中狀態的。現在假設有一個類user,其有一個類型為list的屬性roles,如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
|
public class user { private list<string> roles; public list<string> getroles() { return roles; } public void setroles(list<string> roles) { this .roles = roles; } } |
那么當我們需要展現該user是否擁有某一個role的時候,我們可以使用checkbox標簽來綁定roles數據進行展現。當checkbox標簽的value在我們綁定的列表數據中存在的時候該checkbox將為選中狀態。來看下面一段代碼:
1
2
3
4
5
6
7
8
9
10
11
12
|
<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> |
就上面代碼而言就是當user擁有role1的時候對應的<form:checkbox path="roles" value="role1"/>就會為選中狀態,也就是說roles列表中包含role1的時候該checkbox就會為選中狀態。
1.4.3 綁定一個object數據
checkbox還支持綁定數據類型為object的數據,這種情況下spring會拿所綁定對象數據的tostring結果跟當前checkbox的value進行比較,如果能夠進行匹配則該checkbox將為選中狀態。看這樣一個例子,有一個user類代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
public class user { private blog blog; public blog getblog() { return blog; } public void setblog(blog blog) { this .blog = blog; } } |
blog類的代碼如下:
1
2
3
4
5
6
7
|
public class blog { public string tostring() { return "helloworld" ; } } |
我們可以看到blog類的tostring方法已經被寫死為“helloworld”了。這個時候假設我們往modelmap中放了一個user對象,而且給該user對象設定了一個blog屬性,那么當我們使用該modelmap對象渲染如下視圖代碼時,checkbox標簽的選中狀態是怎樣的呢?
根據前面描述的當checkbox標簽綁定的是一個object對象的時候我們會拿該object對象的tostring和checkbox的value值進行比較,如果匹配則當前checkbox為選中狀態,我們知道這里的checkbox將為選中狀態。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<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標簽
相對于一個checkbox標簽只能生成一個對應的復選框而言,一個checkboxes標簽將根據其綁定的數據生成n個復選框。checkboxes綁定的數據可以是數組、集合和map。在使用checkboxes時我們有兩個屬性是必須指定的,一個是path,另一個是items。items表示當前要用來展現的項有哪些,而path所綁定的表單對象的屬性表示當前表單對象擁有的項,即在items所展現的所有項中表單對象擁有的項會被設定為選中狀態。先來看以下一段代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<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視圖對應著如下的處理器方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
@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對象有三個元素,分別是role1、role2和role3,而我們的表單對象user的roles屬性只擁有兩個元素,分別是role1和role3,,所以當我們訪問該處理器方法返回如上所示的視圖頁面時,我們要展現的復選框項是rolelist,也就是role1、role2和role3,而我們表單對象只擁有role1和role3,所以在頁面進行渲染的時候會展示3個復選框項,但只有role1和role3會被設定為選中狀態。
上面介紹的這種情況是使用list作為展現復選框項的數據源,這種情況我們已經看到了它所呈現出來的標簽label和它的值是一樣的。使用array和set作為數據源也是這種情況。那么如果要讓checkboxes呈現出來的label和實際上送的value不同的話應該怎么做呢?這個時候我們就可以使用map作為數據源了。使用map作為checkboxes的items屬性的數據源時key將作為真正的復選框的value,而map的value將作為label進行展示。當使用map作為checkboxes的items屬性的數據源時我們綁定的表單對象屬性的類型可以是array、集合和map,這種情況就是判斷items map中是否含有對應的key來決定當前的復選框是否處于選中狀態。我們來看以下一個處理器方法以及其對應的視圖代碼。
處理器方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
@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" ; } |
對應的視圖代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<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> |
這個時候我們知道會呈現出3個復選框,而checkboxes綁定的表單對象user的roles屬性是一個集合對象,其包含的兩個元素都能在checkboxes的items數據源中找到對應的key,所以以這兩個元素為value的checkbox將處于選中狀態。效果如下:
當我們使用array或者集合作為數據源,且里面的元素都是一個一個pojo時,我們還可以使用checkboxes標簽的itemlabel和itemvalue屬性來表示使用數組或者集合中元素對象的哪一個屬性作為需要呈現的單選框的label和value。
1.6、radiobutton標簽
radiobutton標簽會被渲染為一個type為radio的普通html input標簽。radiobutton標簽也是可以綁定數據的。以下是一個radiobutton的簡單應用示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<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標簽都是綁定了表單對象user的sex屬性,當sex為1的時候就代表性別為男,上面性別為男的那一行就會被選中,當sex為0的時候就代表性別為女,上面性別為女的那一行就會被選中。
1.7、radiobuttons標簽
radiobuttons標簽跟radiobutton標簽的區別如同checkbox標簽對checkboxes標簽的區別。使用radiobuttons標簽的時候將生成多個單選按鈕。使用radiobuttons有兩個屬性也是我們必須指定的,一個是path屬性,表示綁定的表單對象對應的屬性,另一個是items屬性,表示用于生成單選按鈕的數據源。跟checkboxes一樣,radiobuttons的items屬性和path屬性都可以是array、集合或者是map。現在我們假設user在籃球、足球、乒乓球、羽毛球和排球這5種運動中選擇一種作為自己最喜歡的球類運動。處理器方法和返回的對應的視圖代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@requestmapping (value= "form" , method=requestmethod.get) public string formtag(map<string, object> map) { user user = new user(); user.setfavoriteball( 4 ); //設置我最喜愛的球類運動是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" ; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<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屬性,該屬性表示進行展示的radiobutton之間的分隔符。這里用的是一個空格。結果頁面如下所示:
1.8、password標簽
password標簽將會被渲染為一個type為password的普通html input標簽。
1.9、select標簽
select標簽將會被渲染為一個普通的html select標簽。這里還拿前面的user最喜歡的球類運動來做示例,有如下這樣一個處理器方法和對應的視圖頁面:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@requestmapping (value= "form" , method=requestmethod.get) public string formtag(map<string, object> map) { user user = new user(); user.setfavoriteball( 4 ); //設置我最喜愛的球類運動是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" ; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<form:form action= "formtag/form.do" method= "post" commandname= "user" > <table> <tr> <td>最喜歡的運動:</td> <td> <form:select path= "favoriteball" items= "${ballmap}" /> </td> </tr> <tr> <td colspan= "2" ><input type= "submit" value= "提交" /></td> </tr> </table> </form:form> |
這個時候會渲染出如下結果:
從上面示例我們可以看出,我們通過items屬性給select標簽指定了一個數據源,并且綁定了表單對象user的favoriteball屬性。items屬性是用于指定當前select的所有可選項的,但是它對于select標簽而言不是必須的,因為我們還可以手動的在select標簽中間加上option標簽來指定select可選的option。select標簽支持的items屬性的數據類型可以是array、collection和map,當數據類型為array或collection時且其中的元素為一個pojo時,我們可以通過屬性itemlabel和itemvalue來指定將用于呈現的option label和value,其他情況下array和collection數據源中的元素將既作為可選項option的value又作為它的label。當items的數據類型為map時,map的key將作為可選項option的value,而map的value將作為option的label標簽。
1.10、 option標簽
option標簽會被渲染為一個普通的html option標簽。當一個springmvc select標簽沒有通過items屬性指定自己的數據源的時候,我們就可以在select標簽中通過普通html option標簽或者springmvc option標簽來指定可以選擇的項。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<form:form action= "formtag/form.do" method= "post" commandname= "user" > <table> <tr> <td>最喜歡的運動:</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標簽的數據源的,而是通過在select標簽體里面指定普通html option標簽和springmvc option標簽來指定可選項。其渲染的效果如下:
這個時候你可能會有兩個疑問:
l 如果我在使用select標簽的時候通過items屬性指定了其數據源,同時又在其標簽體里面使用了option標簽,那么這個時候會渲染出什么樣的效果呢?是兩種形式有一個優先級呢,還是會兩種共存呢?
l 從上面代碼產生的效果來看springmvc option標簽跟普通的html option標簽的效果無異,那為什么還要引進一個springmvc option標簽呢?
先來解釋第一個問題,我們把上面的視圖代碼改為如下形式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<form:form action= "formtag/form.do" method= "post" commandname= "user" > <table> <tr> <td>最喜歡的運動:</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標簽加了一個items屬性,然后指定其數據源為當前pagecontext的ballmap屬性。此時,將渲染出如下效果:
答案很明顯,當select標簽指定了items屬性的時候,它會忽略其標簽體的內容,而使用items指定的內容來渲染出可選項。
對于第二個問題,我們把視圖代碼改為如下形式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<form:form action= "formtag/form.do" method= "post" commandname= "user" > <table> <tr> <td>最喜歡的運動:</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> |
我們可以看到,在上面代碼中,我們定義了一個select標簽,其綁定了當前表單對象user的favoriteball屬性,而且我們沒有給該select指定items數據源。值得注意的是在該select標簽體中我們通過普通html option和springmvc option標簽定義了兩個value均為4的option元素,而且我們也知道當前表單對象user的favoriteball屬性的值是4。接著我們來看一下上面代碼渲染出的效果:
接著我們把上述代碼中以springmvc option標簽定義的option給刪除,再看一下其渲染出的效果如下:
由此我們可以看出springmvc option標簽和普通html option標簽的區別就在于普通html option標簽不具備數據綁定功能,而springmvc option標簽具有數據綁定功能,它能把當前綁定的表單對象的屬性對應的值對應的option置為選中狀態。
1.11、options標簽
使用options標簽的時候需要我們指定其items屬性,它會根據其items屬性生成一系列的普通html option標簽。這里的items屬性的可取數據類型及其對應的渲染規則跟select的items屬性是一樣的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<form:form action= "formtag/form.do" method= "post" commandname= "user" > <table> <tr> <td>最喜歡的運動:</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標簽
springmvc textarea標簽將被渲染為普通html textarea標簽。簡單示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<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標簽
springmvc errors標簽是對應于springmvc的errors對象的。它的作用就是用于展現errors對象中包含的錯誤信息的。我們利用errors標簽來展現errors的時候是通過errors標簽的path屬性來綁定一個錯誤信息的。我們可以通過path屬性來展現兩種類型的錯誤信息。
l 所有的錯誤信息,這個時候path的值應該置為“*”
l 當前對象的某一個域的錯誤信息,這個時候path的值應為所需展現的域的名稱
看下面這樣一個例子:
定義了一個uservalidator對象,專門用來對user對象進行驗證,其代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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." ); } } |
然后我們有這樣一個控制器類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@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對象給該類設定了一個用于驗證的uservalidator,這樣當我們請求該控制器的時候uservalidator將生效。
我們有如下這樣一段表單代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<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>所有錯誤信息:</td> <td><form:errors path= "*" /></td> </tr> <tr> <td>name的錯誤信息:</td> <td><form:errors path= "name" /></td> </tr> <tr align= "center" > <td colspan= "2" ><input type= "submit" value= "提交" /></td> </tr> </table> </form:form> |
當我們提交上面的表單的時候會往errors中注入兩個錯誤信息,展示的頁面信息將如下所示:
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。