使用Spring MVC表單標簽


在低版本的Spring中,你必須通過JSTL或<spring:bind>將表單對象綁定到HTML表單頁面中,對於習慣了Struts表單標簽的開發者來說,Spring MVC的這一表現確實讓人失望。不過這一情況已經一去不復返了,從Spring 2.0開始,Spring MVC開始全面支持表單標簽,通過Spring MVC表單標簽,我們可以很容易地將控制器相關的表單對象綁定到HTML表單元素中。 
在上一篇文章《Spring MVC的表單控制器》中(http://tech.it168.com/j/2007-07-26/200707261434046.shtml)我們已經使用到了部分的Spring MVC表單標簽,在本文中我們將對Spring MVC表單標簽進行全面的介紹,讓我們首先從<form:form>標簽開始吧。 

form標簽 
    和使用任何JSP擴展標簽一樣,在使用Spring表單標簽之前,你必須在JSP頁面中添加一行引用Spring表單標簽的聲明,如下所示:

Jsp代碼  復制代碼
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>   
  2. <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> ①引入標簽的聲明   
  3. <html>   
  4. … ②聲明后,在頁面中就可以使用任意Spring表單標簽了   
  5. </html>   
Jsp代碼    收藏代碼
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>  
  2. <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> ①引入標簽的聲明  
  3. <html>  
  4. … ②聲明后,在頁面中就可以使用任意Spring表單標簽了  
  5. </html>   


    一般情況下,我們使用“form”作為Spring MVC表單標簽的前綴,當然只要願意,你可以調整為其它的前綴名。在聲明好標簽引用后,就可以在該JSP文件中使用所有Spring MVC的表單標簽了。下面是一個使用<form:form>表單標簽的示例,它將最終生成一個HTML的 form表單:

Jsp代碼  復制代碼
  1. <form:form>   
  2. 用戶名:<form:input path="userName" /> <br>   
  3. 密 碼:<form:password path="password" /><br>   
  4. Email:<form:input path="email" /><br>   
  5. <input type="submit" value="注冊" name="testSubmit"/>   
  6. <input type="reset" value="重置" />   
  7. </form:form>  
Jsp代碼    收藏代碼
  1. <form:form>  
  2. 用戶名:<form:input path="userName" /> <br>  
  3. 密 碼:<form:password path="password" /><br>  
  4. Email:<form:input path="email" /><br>  
  5. <input type="submit" value="注冊" name="testSubmit"/>  
  6. <input type="reset" value="重置" />  
  7. </form:form>  


     回憶一下我們在《Spring MVC的表單控制器》(http://tech.it168.com/j/2007-07-26/200707261434046.shtml)文章中介紹的用戶注冊表單控制器,用戶通過GET請求調用表單控制器時,表單控制器生成一個新的表單對象,然后重定向到表單輸入頁面。正因為表單頁面是通過訪問表單控制器導向過來的,所以<form:form>標簽本身無需做額外的設置就可以達到以下兩個目標: 
    1) 它不需要象HTML的<form>標簽或Struts的表單標簽一樣通過action屬性指定表單提交的地址。假設和<form:form>標簽對應的控制器的URL是“/registerUser.html”,應用部署目錄為“baobaotao”,則最后產生的HTML代碼自動包含表單提交地址: 
<form id="command" method="post" action="/baobaotao//registerUser.html">…</form> 
    2) <form:form>標簽內部的組件標簽(如<form:input>、<form:password>等)可以直接和表單控制器所對應的表單對象進行值綁定。 

    默認情況下,表單控制器將表單對象以“command”為名放到PageContext中,你可以通過表單控制器commandName屬性的設置使用其它的名字(假設設置為“user”),這時你必須通過<form:form commandName="user">顯式指定綁定的表單對象名稱。 

    除了commandName屬性外,Spring表單標簽擁有豐富的可設置屬性,這些屬性大都是HTML表單標簽屬性的鏡像,如onclick、ondblclick、tabindex等等。需要注意的一點是這些屬性都是小寫的,而對應的HTML標簽的屬性則沒有這個限制。但是有幾個和HTML標簽有區別的屬性,我們通過表 1進行說明: 
    表 1 表單元素標簽特殊屬性 

-------------------- 
目錄    |    說明 
-------------------- 
cssClass  |  使用該屬性指定表單元素CSS樣式名,相當於HTML元素的class屬性。示例:<form:input path="userName" cssClass="inputStyle"/>。 

cssStyle  |  直接通過該屬性指定樣式,相當於HTML元素的style屬性。示例: 
<form:input path="userName" cssStyle="width:100px"/>。 

cssErrorClass  |  cssClass表示表單元素未發生錯誤時對應的樣式,而cssErrorClass表示表單元素發生錯誤時對應的樣式,示例: 
<form:input path="userName" cssClass="sty1" cssErrorClass= "sty2"/> 
-------------------- 

輸入組件標簽 
    表單中有一些用於接受輸入值的組件,如單行文本框、多行文本框以及密碼框,Spring為它們提供了對應的表單標簽,請看下面的例子: 
代碼清單 1 使用輸入組件標簽的表單

Jsp代碼  復制代碼
  1. <form:form>   
  2. 用戶名:<form:input path="userName" /> <br> ①單行文件框標簽   
  3. 密 碼:<form:password path="password" /><br> ②密碼框標簽   
  4. 描 述:<form:textarea path="desc" cols="20" rows="3"/><br> ③多行文件框標簽   
  5. <form:hidden path="times"/> ④隱藏組件的值   
  6. <input type="submit" value="注冊" name="testSubmit"/>   
  7. <input type="reset" value="重置" />   
  8. </form:form>   
Jsp代碼    收藏代碼
  1. <form:form>  
  2. 用戶名:<form:input path="userName" /> <br> ①單行文件框標簽  
  3. 密 碼:<form:password path="password" /><br> ②密碼框標簽  
  4. 描 述:<form:textarea path="desc" cols="20" rows="3"/><br> ③多行文件框標簽  
  5. <form:hidden path="times"/> ④隱藏組件的值  
  6. <input type="submit" value="注冊" name="testSubmit"/>  
  7. <input type="reset" value="重置" />  
  8. </form:form>   


    正如你看到的,所有表單組件標簽都通過path屬性綁定表單對象的屬性值,它支持級聯屬性,比如path="user.userName"將調用表單對象getUser.getUserName()綁定表單對象的屬性值。這些表單組件標簽擁有大多數HTML組件標簽的鏡像屬性,如③處的<form:textarea>就使用了cols和rows屬性設定列數和行數。 

以上使用表單標簽的頁面的對應HTML頁面如下所示: 

Jsp代碼  復制代碼
  1. <form id="command" method="post" action="/baobaotao//registerUser.html">   
  2. 用戶名:<input id="userName" name="userName" type="text" value=""/><br>   
  3. 密 碼: <input id="password" name="password" type="password" value=""/><br>   
  4. 描 述:<textarea id="desc" name="desc" rows="3" cols="20"></textarea><br>   
  5. <input id="times" name="times" type="hidden" value="0"/>   
  6. <input type="submit" value="注冊" name="testSubmit"/>   
  7. <input type="reset" value="重置" />   
  8. </form>   
Jsp代碼    收藏代碼
  1. <form id="command" method="post" action="/baobaotao//registerUser.html">  
  2. 用戶名:<input id="userName" name="userName" type="text" value=""/><br>  
  3. 密 碼: <input id="password" name="password" type="password" value=""/><br>  
  4. 描 述:<textarea id="desc" name="desc" rows="3" cols="20"></textarea><br>  
  5. <input id="times" name="times" type="hidden" value="0"/>  
  6. <input type="submit" value="注冊" name="testSubmit"/>  
  7. <input type="reset" value="重置" />  
  8. </form>   



單選框和復選框組件標簽 
    單選框和復選框組件雖然在HTML中都對應<input>元素標簽,但在Spring MVC表單標簽中,它們分別對應兩個更達意的標簽:    

Jsp代碼  復制代碼
  1. <form:radiobutton>和<form:checkbox>。   
  2. radiobutton   
  3. 單選框組件由兩個同名的標簽組件組成,當表單對象對應屬性值和value值相等時,單選框選中。下面是一個代表性別的單選框:   
  4. <form:form>   
  5. 性 別:<form:radiobutton path="sex" value="0"/>男   
  6. <form:radiobutton path="sex" value="1"/>女   
  7. </form:form>   
  8. 當表單對象的sex屬性為0時(可以是String、int等可以自動轉換為String的類型),所生成的HTML代碼如下所示:   
  9. <form id="command" method="post" action="/baobaotao//registerUser.html">   
  10. 性 別:<input id="sex1" name="sex" type="radio" value="0" checked="checked"/>男   
  11. <input id="sex2" name="sex" type="radio" value="1"/>女   
  12. </form>    
Jsp代碼    收藏代碼
  1. <form:radiobutton>和<form:checkbox>。  
  2. radiobutton  
  3. 單選框組件由兩個同名的標簽組件組成,當表單對象對應屬性值和value值相等時,單選框選中。下面是一個代表性別的單選框:  
  4. <form:form>  
  5. 性 別:<form:radiobutton path="sex" value="0"/>男  
  6. <form:radiobutton path="sex" value="1"/>女  
  7. </form:form>  
  8. 當表單對象的sex屬性為0時(可以是String、int等可以自動轉換為String的類型),所生成的HTML代碼如下所示:  
  9. <form id="command" method="post" action="/baobaotao//registerUser.html">  
  10. 性 別:<input id="sex1" name="sex" type="radio" value="0" checked="checked"/>男  
  11. <input id="sex2" name="sex" type="radio" value="1"/>女  
  12. </form>    



checkbox 
    復選框組件標簽相對來說復雜一些,復選框組件對應的表單屬性不但可以boolean類型,還可以是String[]、Collection,Enum等類型。針對不同屬性類型,復選框的選中狀態的判斷條件是不一樣的: 
 boolean類型:當對應屬性為true時,該復選框選中(一個屬性僅對應一個復選框); 
 String[]、Collection或Enum類型:復選框對應值出現在對應屬性列表中,該復選框選中; 
 其它類型:當復選框對應的值可以轉換為對應屬性值,該復選框選中。 
假設用戶注冊的User表單對象包含了一個List類型的favorites屬性:

Java代碼  復制代碼
  1. import java.util.List;    
  2. public class User {    
  3. private List favorites;    
  4. public List getFavorites() {    
  5. return favorites;    
  6. }    
  7. public void setFavorites(List favorites) {    
  8. this.favorites = favorites;    
  9. }    
  10. }   
Java代碼    收藏代碼
  1. import java.util.List;   
  2. public class User {   
  3. private List favorites;   
  4. public List getFavorites() {   
  5. return favorites;   
  6. }   
  7. public void setFavorites(List favorites) {   
  8. this.favorites = favorites;   
  9. }   
  10. }   


我們希望將其在頁面中使用一個復選框組件綁定這個屬性,則可以使用以下的代碼: 
代碼清單 2 復選框標簽的使用

Jsp代碼  復制代碼
  1. <form:form>    
  2. 興趣愛好:    
  3. <form:checkbox path="favorites" value="1"/>computer    
  4. <form:checkbox path="favorites" value="2"/>sport    
  5. <form:checkbox path="favorites" value="3"/>entertainment    
  6. <form:checkbox path="favorites" value="4"/>literature    
  7. </form:form>   
Jsp代碼    收藏代碼
  1. <form:form>   
  2. 興趣愛好:   
  3. <form:checkbox path="favorites" value="1"/>computer   
  4. <form:checkbox path="favorites" value="2"/>sport   
  5. <form:checkbox path="favorites" value="3"/>entertainment   
  6. <form:checkbox path="favorites" value="4"/>literature   
  7. </form:form>   


除了正常的path屬性名外,還必須提供一個value屬性,假設User表單對象的favorites屬性包括了1和3的值,那么產生的HTML頁面為:

Html代碼  復制代碼
  1. <form id="command" method="post" action="/baobaotao//registerUser.html">    
  2. 興趣愛好:<input id="favorites1" name="favorites" type="checkbox" value="1" checked="checked"/>    
  3. <input type="hidden" value="1" name="_favorites"/>computer    
  4. <input id="favorites2" name="favorites" type="checkbox" value="2" />    
  5. <input type="hidden" value="1" name="_favorites"/>sport    
  6. <input id="favorites3" name="favorites" type="checkbox" value="3" checked="checked"/>    
  7. <input type="hidden" value="1" name="_favorites"/>entertainment    
  8. <input id="favorites4" name="favorites" type="checkbox" value="4"/>    
  9. <input type="hidden" value="1" name="_favorites"/>literature    
  10. </form>   
Html代碼    收藏代碼
  1. <form id="command" method="post" action="/baobaotao//registerUser.html">   
  2. 興趣愛好:<input id="favorites1" name="favorites" type="checkbox" value="1" checked="checked"/>   
  3. <input type="hidden" value="1" name="_favorites"/>computer   
  4. <input id="favorites2" name="favorites" type="checkbox" value="2" />   
  5. <input type="hidden" value="1" name="_favorites"/>sport   
  6. <input id="favorites3" name="favorites" type="checkbox" value="3" checked="checked"/>   
  7. <input type="hidden" value="1" name="_favorites"/>entertainment   
  8. <input id="favorites4" name="favorites" type="checkbox" value="4"/>   
  9. <input type="hidden" value="1" name="_favorites"/>literature   
  10. </form>   



大家可能已經注意到每個復選框組件的后台都跟着一個隱藏組件,這是因為當HTML頁面中的復選框沒有被選中時,這個復選框的值不會在表單提交時作為HTTP請求參數發送到服務器端,這給Spring的表單數據綁定造成了麻煩——因為無法觸發setFavorites()方法的調用(如果原來已經有值,這個值不會被設置為空)。解決方法就是在每個復選框后面加一個隱藏組件,並且將對應的復選框名字前添加一個下划線("_")作為隱藏組件的名字。這樣一來,你相當於告訴Spring“這個表單中存在這樣一個復選框,我希望表單對象中對應的屬性和這個checkbox的狀態保持一致”。 
假設復選框對應的選項在數據庫或配置文件中定義,那么頁面復選框標簽就不能通過硬編碼的方式指定,相反必須根據配置的選項數據動態產生。對於這樣的需求,代碼清單 2的編寫方式顯然不能滿足需求。回憶一下表單控制器的工作流程,我們知道可以通過復寫referenceData()方法在表單顯示前准備一些需要的數據,現在終於派上用場了,來看一下具體的實現: 

代碼清單 3 UserRegisterController:准備表單顯示數據

Java代碼  復制代碼
  1. package com.baobaotao.web.user;   
  2. …   
  3. import org.springframework.ui.ModelMap;   
  4. public class UserRegisterController extends SimpleFormController {   
  5. private BbtForum bbtForum;   
  6. ①創建初始表單對象   
  7. protected Object formBackingObject(HttpServletRequest request)   
  8. throws Exception {   
  9. int userId = ServletRequestUtils.getIntParameter(request, "userId",-1);   
  10. User user = bbtForum.getUser(userId);   
  11. user.setUserName("tom");   
  12. List favorites = new ArrayList();①-1默認選中值為13的選項   
  13. favorites.add("1");   
  14. favorites.add("3");   
  15. user.setFavorites(favorites);   
  16. return user;   
  17. }   
  18. @Override ②准備表單顯示時需要的數據   
  19. protected Map referenceData(HttpServletRequest request) throws Exception {   
  20. Map favoriteMap = new LinkedHashMap();   
  21. favoriteMap.put("1", "computer");   
  22. favoriteMap.put("2", "sport");   
  23. favoriteMap.put("3", "entertainment");   
  24. favoriteMap.put("4", "literature");   
  25. ②-1將表單頁面需要的對象以ModelMap返回,最終將以屬性名值對方式出現在請求屬性中   
  26. return new ModelMap().addObject("favoriteMap", favoriteMap);   
  27. }   
  28. @Override  
  29. protected ModelAndView onSubmit(Object command, BindException errors)   
  30. throws Exception {   
  31. User user = (User) command;   
  32. bbtForum.registerUser(user);   
  33. return new ModelAndView(getSuccessView(), "user", user);   
  34. }   
  35. }   
Java代碼    收藏代碼
  1. package com.baobaotao.web.user;  
  2. …  
  3. import org.springframework.ui.ModelMap;  
  4. public class UserRegisterController extends SimpleFormController {  
  5. private BbtForum bbtForum;  
  6. ①創建初始表單對象  
  7. protected Object formBackingObject(HttpServletRequest request)  
  8. throws Exception {  
  9. int userId = ServletRequestUtils.getIntParameter(request, "userId",-1);  
  10. User user = bbtForum.getUser(userId);  
  11. user.setUserName("tom");  
  12. List favorites = new ArrayList();①-1默認選中值為13的選項  
  13. favorites.add("1");  
  14. favorites.add("3");  
  15. user.setFavorites(favorites);  
  16. return user;  
  17. }  
  18. @Override ②准備表單顯示時需要的數據  
  19. protected Map referenceData(HttpServletRequest request) throws Exception {  
  20. Map favoriteMap = new LinkedHashMap();  
  21. favoriteMap.put("1", "computer");  
  22. favoriteMap.put("2", "sport");  
  23. favoriteMap.put("3", "entertainment");  
  24. favoriteMap.put("4", "literature");  
  25. ②-1將表單頁面需要的對象以ModelMap返回,最終將以屬性名值對方式出現在請求屬性中  
  26. return new ModelMap().addObject("favoriteMap", favoriteMap);  
  27. }  
  28. @Override  
  29. protected ModelAndView onSubmit(Object command, BindException errors)  
  30. throws Exception {  
  31. User user = (User) command;  
  32. bbtForum.registerUser(user);  
  33. return new ModelAndView(getSuccessView(), "user", user);  
  34. }  
  35. }   



在以上代碼中我們覆蓋了SimpleFormController的referenceData()和formBackingObject ()方法。參照《Spring MVC的表單控制器》中(http://tech.it168.com/j/2007-07-26/200707261434046.shtml)介紹的表單控制器工作流程,可以知道formBackingObject()方法用於表單頁面初始化時使用的表單對象。我們在formBackingObject()方法中,將User的favorites屬性的初始值設置為1和3(分別對應computer和entertainment的選項),如①所示。 
在②處,我們覆蓋了referenceData()方法,該方法為表單頁面准備一些數據。該方法返回值類型為Map,該Map的鍵值將會綁定到請求的屬性中。ModelMap是Spring 2.0新增的Map實現類,它提供了鏈式方法和默認鍵值的機制。這里,我們使用ModelMap綁定了一個鍵為“favoriteMap”,值為favoriteMap的數據對象。favoriteMap是所有興趣愛好的選項,在實際的應用中,你可以從數據庫中或配置文件中進行加載。 
當請求中綁定了favoriteMap時,對應的表單頁面就可以遍歷該Map並動態構造出復選框列表了:

Jsp代碼  復制代碼
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>   
  2. <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>   
  3. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>   
  4. <html>   
  5. <head>   
  6. <title>寶寶淘論壇用戶注冊</title>   
  7. </head>   
  8. <body>   
  9. <form:form>   
  10. …   
  11. 興趣愛好:   
  12. <c:forEach items="${favoriteMap}" var="favorite">①引用favoriteMap的請求屬性   
  13. ②引用Map的鍵和值   
  14. <form:checkbox path="favorites" value="${favorite.key}" />${favorite.value}   
  15. </c:forEach>   
  16. <input type="submit" value="注冊" name="testSubmit"/>   
  17. <input type="reset" value="重置" />   
  18. </form:form>   
  19. </body>   
  20. </html>   
Jsp代碼    收藏代碼
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>  
  2. <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>  
  3. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  
  4. <html>  
  5. <head>  
  6. <title>寶寶淘論壇用戶注冊</title>  
  7. </head>  
  8. <body>  
  9. <form:form>  
  10. …  
  11. 興趣愛好:  
  12. <c:forEach items="${favoriteMap}" var="favorite">①引用favoriteMap的請求屬性  
  13. ②引用Map的鍵和值  
  14. <form:checkbox path="favorites" value="${favorite.key}" />${favorite.value}  
  15. </c:forEach>  
  16. <input type="submit" value="注冊" name="testSubmit"/>  
  17. <input type="reset" value="重置" />  
  18. </form:form>  
  19. </body>  
  20. </html>   



    在①處,我們通過JSTL標簽對屬性名為favoriteMap的模型數據對象進行遍歷,為每一個元素項生成一個復選框。注意②處的復選框代碼,它有兩個明顯的特征:1)使用Spring復選框標簽;2)通過EL引用Map類型的模型數據。由於favorite是Map類型,所以我們可以通過${favorite.key}和${favorite.value}引用Map元素的鍵和值。 

    提示: 
    對於同時使用JSTL和Spring表單標簽的JSP文件,JSTL的標簽會被首先解析,然后再解析Spring表單標簽,因此如實例那樣混合使用二者可以如預期一樣輸出正確的結果。 

下拉框組件標簽 
    下拉框標簽的典型形式為: <form:select path="city" items="${cityList}"/>,它包括兩方面的數據:1)對應表單對象屬性值(city);2)用於構造整個下拉框選項的數據(cityList)。嚴格地說,下拉框組件分為單選和多選兩種形式,當表單對象對應屬性為復數形態的類型時(如String[]、List、Set),產生的目標組件為多選下拉框,反之為單選下拉框。 
用於構造下拉框選項的數據也必須在referenceData()方法中准備好(可能從數據庫字典表中加載或從外部配置文件中加載): 
代碼清單 4 UserRegisterController:為下拉框標簽准備數據 

Java代碼  復制代碼
  1. package com.baobaotao.web.user;   
  2. …   
  3. public class UserRegisterController extends SimpleFormController {   
  4. @Override  
  5. protected Map referenceData(HttpServletRequest request) throws Exception {   
  6. Map favoriteMap = new LinkedHashMap();   
  7. favoriteMap.put("1", "computer");   
  8. favoriteMap.put("2", "sport");   
  9. favoriteMap.put("3", "entertainment");   
  10. favoriteMap.put("4", "literature");   
  11. List cityList = new ArrayList();①為下拉框選項准備的數據   
  12. cityList.add("北京");   
  13. cityList.add("上海");   
  14. cityList.add("天津");   
  15. cityList.add("廈門");   
  16. return new ModelMap()   
  17. .addObject("favoriteMap", favoriteMap)   
  18. .addObject("cityList", cityList);   
  19. }   
  20. …   
  21. }  
Java代碼    收藏代碼
  1. package com.baobaotao.web.user;  
  2. …  
  3. public class UserRegisterController extends SimpleFormController {  
  4. @Override  
  5. protected Map referenceData(HttpServletRequest request) throws Exception {  
  6. Map favoriteMap = new LinkedHashMap();  
  7. favoriteMap.put("1", "computer");  
  8. favoriteMap.put("2", "sport");  
  9. favoriteMap.put("3", "entertainment");  
  10. favoriteMap.put("4", "literature");  
  11. List cityList = new ArrayList();①為下拉框選項准備的數據  
  12. cityList.add("北京");  
  13. cityList.add("上海");  
  14. cityList.add("天津");  
  15. cityList.add("廈門");  
  16. return new ModelMap()  
  17. .addObject("favoriteMap", favoriteMap)  
  18. .addObject("cityList", cityList);  
  19. }  
  20. …  
  21. }  



這時,生成的下拉框HTML代碼如下所示:

Html代碼  復制代碼
  1. <select id="city" name="city" > ①   
  2. <option value="北京">北京</option>  
  3. <option value="上海">上海</option>  
  4. <option value="天津">天津</option>  
  5. <option value="廈門">廈門</option>  
  6. </select>  
  7. <input type="hidden" name="_city" value="1"/> ②   
Html代碼    收藏代碼
  1. <select id="city" name="city" > ①  
  2. <option value="北京">北京</option>  
  3. <option value="上海">上海</option>  
  4. <option value="天津">天津</option>  
  5. <option value="廈門">廈門</option>  
  6. </select>  
  7. <input type="hidden" name="_city" value="1"/> ②   




    首先,我們注意到②處有一個和復選框組件相似的配套隱藏組件,之所以會需要這個隱藏組件是出於和復選框相同的原因。下拉框的值和標簽是相同的,都是cityList列表中的元素值。在實際應用中,我們一般為每一個選項提供一個代碼,而非采用和標簽相同的值,這樣可以使用規范簡短的代碼保存數據,為后續的查詢、引用帶來方便。這時,可以采用下拉框標簽的另一種屬性設置方式: 
<form:select path="city" items="${cityMap}" itemValue="key" itemLabel="value"/> 
cityMap是一個已經通過referenceData()方法准備好的Map對象,itemValue對應下拉框的value屬性,而itemValue="key"表示使用cityMap元素的鍵,itemLable對應下拉框的標簽值, itemLabel="value"表示使用cityMap元素的值。實際上,items屬性所綁定的也可以是一個List對象,其元素可以是一個JavaBean,這時可以通過itemValue和itemLabel指定引用JavaBean的屬性。如下所示: 
<form:select path="city" items="${cities}" itemValue="code" itemLabel="name"/> 
cities對應一個通過referenceData()方法准備好的List對象,其元素為City對象,City對象包括code和name兩個屬性。通過以上這些方式,我們可以得到一個選項的值和標簽不相同的下拉框: 
<select id="city" name="city"> 
<option value="1">北京</option> 
<option value="2">上海</option> 
<option value="3">天津</option> 
<option value="4" >廈門</option> 
</select> 
<input type="hidden" name="_city" value="1"/> 
一般情況下,下拉框會提供一個類似於“請選擇”或“--未選擇--”的默認選項,這個選項本身不是有效的數據項,它們的存在僅僅為提示用戶作選擇或代表一個未作選擇的空值。這時,我們可能會考慮手工提供一個下拉框選項,而其它的選項通過referenceData()提供的數據動態生成: 
<form:select path="city"> 
<form:option value="" label="--請選擇--"/> ①提示性的選項 
<form:options items="${cityMap}" itemValue="key" itemLabel="value"/>②真實的選項數據 
</form:select> 
這樣產生的下拉框在默認情況下將顯示①處對應的選項,如果用戶沒有選擇,選項相當於是一個空值。②處對應的<form:options>會將cityMap的數據轉換為下拉框選項列表。 


錯誤標簽 
    錯誤標簽是和服務端校驗信息關聯的對應物,假設在服務端通過以下代碼對表單數據進行校驗: 
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userName","required.username", "用戶名必須填寫"); 
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password","required.password", "密碼不能為空"); 

    當提交的表單數據不合法引發校驗錯誤時,提交的表單將被駁回,請求被重定向到表單輸入頁面,在該頁面中通過 

Jsp代碼  復制代碼
  1. <form:errors>標簽就可以顯示出校驗的錯誤信息:   
  2. <form:form>   
  3. 用戶名:<form:input path="userName" cssClass="inputStyle" cssErrorClass="asdfe"/>   
  4. <font color="red"><form:errors path="userName" /></font>   
  5. <br>   
  6. 密 碼:<form:password path="password" />   
  7. <font color="red"><form:errors path="password" /></font>   
  8. <br>   
  9. </form:form>   
Jsp代碼    收藏代碼
  1. <form:errors>標簽就可以顯示出校驗的錯誤信息:  
  2. <form:form>  
  3. 用戶名:<form:input path="userName" cssClass="inputStyle" cssErrorClass="asdfe"/>  
  4. <font color="red"><form:errors path="userName" /></font>  
  5. <br>  
  6. 密 碼:<form:password path="password" />  
  7. <font color="red"><form:errors path="password" /></font>  
  8. <br>  
  9. </form:form>   



    通過path和表單對象特定屬性錯誤信息進行綁定,一個表單對象屬性可能包括一個或多個錯誤信息,也可以沒有錯誤信息,<form:errors>會根據錯誤信息的情況進行合理的展示。此外,path還支持通配符匹配的表示方式: 
 path="*": 顯示所有的錯誤信息; 
 path="lastName*": 顯示所有屬性名前綴為lastName的錯誤信息。 

小結 
    在Spring 2.0中,新增的表單標簽是Spring MVC的一個顯著的升級,它可以綁定服務端的表單對象,讓頁面數據的渲染工作變得輕松。因為Spring MVC框架本身的優越性,使得許多Spring MVC表單標簽無需進行過多的屬性設置就可以正確使用,因此相比於Struts的表單標簽,Spring MVC在使用上更加方便,更加輕松。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM