原文地址:https://blog.csdn.net/hp_yangpeng/article/details/51906654html
在使用SpringMVC的時候咱們可使用Spring封裝的一系列表單標籤,這些標籤均可以訪問到ModelMap中的內容。下面將對這些標籤一一介紹。java
在正式介紹SpringMVC的表單標籤以前,咱們須要先在JSP中聲明使用的標籤,具體作法是在JSP文件的頂部加入如下指令:web
- <%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
1.1 form標籤
使用Spring的form標籤主要有兩個做用,第一是它會自動的綁定來自Model中的一個屬性值到當前form對應的實體對象,默認是command屬性,這樣咱們就能夠在form表單體裏面方便的使用該對象的屬性了;第二是它支持咱們在提交表單的時候使用除GET和POST以外的其餘方法進行提交,包括DELETE和PUT等。spring
1.1.1 支持綁定表單對象
咱們先來看以下使用form標籤的一個示例:數組
- <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」時,那麼它在渲染時就會生成以下一段代碼:app
- <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="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。ide
咱們指定form默認自動綁定的是Model的command屬性值,那麼當個人form對象對應的屬性名稱不是command的時候,應該怎麼辦呢?對於這種狀況,Spring給咱們提供了一個commandName屬性,咱們能夠經過該屬性來指定咱們將使用Model中的哪一個屬性做爲form須要綁定的command對象。除了commandName屬性外,指定modelAttribute屬性也能夠達到相同的效果。這裏假設上面代碼中咱們存放在Model中的是user對象而不是默認的command對象,那麼咱們的代碼就能夠以下定義了:post
- <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>
在上面代碼中咱們設定了該form的提交方法是delete,這樣在後臺咱們就能夠給對應的請求方法的RequestMapping加上method爲RequestMethod.DELETE的限制。咱們來看一下上面的代碼在進行渲染的時候會生成怎樣的Html代碼,其生成的代碼以下所示:this
- <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>
- <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中加上以下代碼:url
- <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>
- <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將不會生效。
- <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屬性來指定。以下面這個示例:
- <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對應的值。
- <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>
- <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來指定。
- <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>
- <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標籤的時候順帶介紹過了,這裏就再也不過多的贅述了。
- <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對應不選中。
- <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,以下所示:
- public class User {
-
- private List<String> roles;
-
- public List<String> getRoles() {
- return roles;
- }
-
- public void setRoles(List<String> roles) {
- this.roles = roles;
- }
- }
- 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將爲選中狀態。來看下面一段代碼:
- <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類代碼以下:
- public class User {
-
- private Blog blog;
-
- public Blog getBlog() {
- return blog;
- }
-
- public void setBlog(Blog blog) {
- this.blog = blog;
- }
- }
- 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";
- }
-
- }
- 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將爲選中狀態。
- <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所展示的全部項中表單對象擁有的項會被設定爲選中狀態。先來看如下一段代碼:
- <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視圖對應着以下的處理器方法:
- @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";
- }
- @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對象有三個元素,分別是role一、role2和role3,而咱們的表單對象User的roles屬性只擁有兩個元素,分別是role1和role3,,因此當咱們訪問該處理器方法返回如上所示的視圖頁面時,咱們要展示的複選框項是roleList,也就是role一、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來決定當前的複選框是否處於選中狀態。咱們來看如下一個處理器方法以及其對應的視圖代碼。
處理器方法:
- @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";
- }
- @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";
- }
對應的視圖代碼:
- <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的簡單應用示例:
- <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種運動中選擇一種做爲本身最喜歡的球類運動。處理器方法和返回的對應的視圖代碼以下:
- @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";
- }
- @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";
- }
- <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最喜歡的球類運動來作示例,有以下這樣一個處理器方法和對應的視圖頁面:
- @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";
- }
- @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";
- }
- <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標籤來指定能夠選擇的項。
- <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標籤呢?
先來解釋第一個問題,咱們把上面的視圖代碼改成以下形式:
- <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指定的內容來渲染出可選項。
對於第二個問題,咱們把視圖代碼改成以下形式:
- <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屬性是同樣的。
- <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標籤。簡單示例以下:
- <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對象進行驗證,其代碼以下:
- 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.");
- }
-
- }
- 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.");
- }
-
- }
而後咱們有這樣一個控制器類:
- @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";
- }
- }
- @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將生效。
咱們有以下這樣一段表單代碼:
- <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中注入兩個錯誤信息,展現的頁面信息將以下所示: