SpringMVC表單標籤簡介

KeepTing發表於2017-03-06

在使用SpringMVC的時候我們可以使用Spring封裝的一系列表單標籤,這些標籤都可以訪問到ModelMap中的內容。下面將對這些標籤一一介紹。

在正式介紹SpringMVC的表單標籤之前,我們需要先在JSP中宣告使用的標籤,具體做法是在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標籤的一個示例:

 

Jsp程式碼  收藏程式碼
<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”時,那麼它在渲染時就會生成如下一段程式碼:

Html程式碼  收藏程式碼
<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物件,那麼我們的程式碼就可以如下定義了:

Jsp程式碼  收藏程式碼
<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請求方法

Jsp程式碼  收藏程式碼
<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程式碼,其生成的程式碼如下所示:

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在實現除GET和POST之外的請求方法時,還是使用的POST方法進行請求,然後給表單加上了一個隱藏域,用以表示真正的請求方法,這個隱藏域的名稱預設是“_method”。上面這樣定義之後是不是就意味著我們可以以delete方式訪問到“formTag/form.do”了呢?答案是不行的。這樣定義我們只是多加了一個用以表示請求方法的隱藏域而已,實際的請求方式還是POST。Spring為我們提供了一個Filter——HiddenHttpMethodFilter,通過這個Filter我們可以把以POST方式傳遞過來的表示實際請求方式的引數轉換為對應的真正的Http請求方法。所以這個時候我們還需要在web.xml中加上如下程式碼:

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方式進行傳遞的表示請求方式的隱藏域轉換為真正的Http請求方式。當我們直接在form:form標籤的method中使用除GET和POST方法以外的其他方法時,Spring會自動生成以POST方式進行傳遞的表單以及對應的隱藏域。所以當我們需要手動的設定表示請求方法的隱藏域時,我們就需要指定表單的請求方式為POST,為GET將不會生效。

Jsp程式碼  收藏程式碼
<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屬性來指定。如下面這個示例:

Jsp程式碼  收藏程式碼
<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對應的值。

Xml程式碼  收藏程式碼
<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來指定。

Xml程式碼  收藏程式碼
<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標籤的時候順帶介紹過了,這裡就不再過多的贅述了。

Jsp程式碼  收藏程式碼
<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對應不選中。

Jsp程式碼  收藏程式碼
<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,如下所示:

Java程式碼  收藏程式碼
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將為選中狀態。來看下面一段程式碼:

Jsp程式碼  收藏程式碼
<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類程式碼如下:

Java程式碼  收藏程式碼
public class User {  
   
    private Blog blog;  
     
    public Blog getBlog() {  
       return blog;  
    }  
   
    public void setBlog(Blog blog) {  
       this.blog = blog;  
    }  
}  

 

Blog類的程式碼如下:

Java程式碼  收藏程式碼
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將為選中狀態。

Jsp程式碼  收藏程式碼
<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所展現的所有項中表單物件擁有的項會被設定為選中狀態。先來看以下一段程式碼:

Jsp程式碼  收藏程式碼
<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檢視對應著如下的處理器方法:

Java程式碼  收藏程式碼
@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來決定當前的核取方塊是否處於選中狀態。我們來看以下一個處理器方法以及其對應的檢視程式碼。

處理器方法:

Java程式碼  收藏程式碼
@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";  
}  

 

對應的檢視程式碼:

Jsp程式碼  收藏程式碼
<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的簡單應用示例:

Jsp程式碼  收藏程式碼
<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種運動中選擇一種作為自己最喜歡的球類運動。處理器方法和返回的對應的檢視程式碼如下:

Java程式碼  收藏程式碼
@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";  
}  

 

 

Jsp程式碼  收藏程式碼
<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最喜歡的球類運動來做示例,有如下這樣一個處理器方法和對應的檢視頁面:

Java程式碼  收藏程式碼
@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";  
}  

 

 

Jsp程式碼  收藏程式碼
<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標籤來指定可以選擇的項。

Jsp程式碼  收藏程式碼
<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標籤呢?

先來解釋第一個問題,我們把上面的檢視程式碼改為如下形式:

Jsp程式碼  收藏程式碼
<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指定的內容來渲染出可選項。

       對於第二個問題,我們把檢視程式碼改為如下形式:

Jsp程式碼  收藏程式碼
<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屬性是一樣的。

Jsp程式碼  收藏程式碼
<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標籤。簡單示例如下:

Jsp程式碼  收藏程式碼
<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物件進行驗證,其程式碼如下:

Java程式碼  收藏程式碼
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.");  
    }  
   
}  

 

 

       然後我們有這樣一個控制器類:

Java程式碼  收藏程式碼
@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將生效。

 

       我們有如下這樣一段表單程式碼:

Jsp程式碼  收藏程式碼
<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中注入兩個錯誤資訊,展示的頁面資訊將如下所示:

 

相關文章