SpringMVC——數據綁定及表單標簽
理解數據綁定
為什么要使用數據綁定
基於HTTP特性,所有的用戶輸入的請求參數類型都是String,比如下面表單:

按照我們以往所學,如果要獲取請求的所有參數的話,我們需要這樣寫:
public String saveProduct(String name,String description,Integer price)
{....}
但是我們發現這些參數都是描述一類事物的屬性信息的,並且如果參數過多的話,將會加大我們修改和編寫的負擔。數據綁定是將用戶輸入綁定到Java對象的一種特性。
我們可以這樣理解,我們定義一個Java類Product,擁有name、price、description等屬性,當請求映射時,可以直接把請求的參數自動注入到一個Product對象中。
有了數據綁定后,SpringMVC將會為我們自動進行格式轉換,我們如下編寫即可:
public String saveProduct(Produc product, RedirectAttributes redirectAttributes)
{....}
這無疑將是方便的!
表單標簽庫
加入taglib指令
表單標簽庫包含了可以用在JSP頁面中渲染HTML元素的標簽。
為了使用這些標簽,必須在開頭聲明這個taglib指令
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
表單標簽庫中的所有標簽:
| 標簽 | 描述 |
|---|---|
| form | 渲染表單元素 |
| input | 渲染<input type="text"/> |
| password | 渲染<input type="password"/> |
| hidden | 渲染<input type="hidden"/> |
| textarea | 渲染textare元素 |
| checkbox | 渲染<input type="checkbox"/> |
| checkboxes | 渲染多個<input type="checkbox"/> |
| radiobutton | 渲染一個<input type="radio"/> |
| radiobuttons | 渲染多個<input type="radio"/> |
| select | 渲染一個選擇元素 |
| option | 渲染一個可選元素 |
| options | 渲染一個可被選擇元素列表 |
| errors | 在span元素中渲染字段錯誤 |
表單標簽
實現的效果
具體的表單標簽的用法,請詳情查看原文章(http://elim.iteye.com/blog/1807330).
下面我僅僅以我的實例,來說明用到的表單標簽:
我們的實現效果:
1.圖書列表界面:

2.圖書編輯界面:

思路分析
1.首先我們在圖書列表界面中,點擊鏈接后,會訪問book_edit/${book.id}。
<body>
<a href="<c:url value="/book_input"/>">Add Book</a>
<table>
<tr>
<th>Category</th>
<th>Title</th>
<th>ISBN</th>
<th>Author</th>
<th> </th>
</tr>
<c:forEach items="${books}" var="book">
<tr>
<td>${book.category.name}</td>
<td>${book.title}</td>
<td>${book.isbn}</td>
<td>${book.author}</td>
<td><a href="book_edit/${book.id}">Edit</a> </td>
</tr>
</c:forEach>
</table>
</body>
2.Controller接收到請求會保存類別信息和圖書信息到Model中。
@RequestMapping(value = "/book_edit/{id}")
public String bookSave(Model model, @PathVariable int id)
{
List<Category> categories=bookService.getAllCategorys();
model.addAttribute("categories",categories);
Book book= bookService.get(id);
model.addAttribute("book",book);
return "BookEditForm";
}
3.使用表單標簽,綁定requestScope中的Book對象和Category對象到表單中。
<body>
<form:form commandName="book" action="book_update" method="post">
<legend>Edit a Book</legend>
<p>
<label for="category">Category:</label>
<form:select id="category" path="category.id" items="${categories}" itemLabel="name" itemValue="id"/>
</p>
<p>
<label for="title">Title:</label>
<form:input id="title" path="title"/>
</p>
<p>
<label for="author">Author:</label>
<form:input id="author" path="author"/>
</p>
<p>
<label for="isbn">ISBN:</label>
<form:input id="title" path="isbn"/>
</p>
<p>
<input type="reset">
<input type="submit" value="Update Book">
</p>
</form:form>
</body>
表單標簽之FORM
使用Spring的form標簽主要有兩個作用:
第一是它會自動的綁定來自Model中的一個屬性值到當前form對應的實體對象,默認是command屬性,這樣我們就可以在form表單體里面方便的使用該對象的屬性了;但是我們要使用的Model中的Book,而非默認的command,所以我們可以將保存在Model中的Book鍵值對的鍵值改為command或者在form中指定commandName,即commandName="book"
第二是它支持我們在提交表單的時候使用除GET和POST之外的其他方法進行提交,包括DELETE和PUT等。
<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 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”。
但此時我們還需要在Web.XML中添加:
詳情請查看:SpringMVC:學習筆記(3)——REST<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>
表單標簽之Input
SpringMVC的input標簽會被渲染為一個type為text的普通Html input標簽,這個標簽最重要的屬性時PATH,它將這個輸入字段綁定到book的一個屬性,即綁定到Book的標題屬性。
<p>
<label for="title">Title:</label>
<form:input id="title" path="title"/>
</p>
使用SpringMVC的input標簽的唯一作用就是它能綁定表單數據。SpringMVC表單標簽最大的好處就是它支持數據綁定,當我們的表單標簽不需要綁定的數據的時候,我們應該使用普通的Html標簽。關於input標簽綁定表單數據的方法已經在介紹form標簽的時候順帶介紹過了,這里就不再過多的贅述了
表單標簽之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";
}
前端視圖
<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>
渲染效果
這個時候會渲染出如下結果:

相關說明
從上面示例我們可以看出:
1.通過items屬性給select標簽指定了一個數據源,並且綁定了表單對象user的favoriteBall屬性。
說明:
Items屬性是用於指定當前select的所有可選項的,但是它對於select標簽而言不是必須的,因為我們還可以手動的在select標簽中間加上option標簽來指定select可選的option。
2.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標簽。
