雖然咱們可使用HTML原生的form表單標籤來輕鬆的寫出一個表單,其實我一直都是這樣作的,可是使用Spring表單標籤能夠更方便咱們完成例如:驗證失敗後表單數據的回填功能(雖然你可使用EL+JSTL來實現),可是使用spring表單標籤更爲方便。css
如同使用JSTL同樣,咱們須要先在JSP頁面中使用taglib指令導入:html
<%@taglib prefix="form" uri="http://www.springframeork.org/tags/form" %>
表單標籤庫中的標籤:spring
標籤 | 描述 |
form | 渲染表單元素 |
input | 渲染<input type="text">元素 |
password | 渲染<input type="password">元素 |
hidden | 渲染<input type="hidden">元素 |
textarea | 渲染textarea |
checkbox | 渲染一個<input type="checkbox"> |
checkboxes | 渲染多個<input type="checkbox"> |
radiobutton | 渲染一個<input type="radio"> |
radiobuttons | 渲染多個<input type="radio"> |
select | 渲染一個select元素 |
option | 渲染一個可選元素 |
errors | 在span元素中渲染字段錯誤 |
表單標籤用於渲染HTML表單,要使用渲染一個表單輸入字段的任何其餘標籤,必須有一個form標籤。數據庫
commandName屬性或許是其中最爲重要的屬性,由於它定義了模型屬性的名稱,該值要求與返回該表單視圖的請求處理方法中模型名一致。commandName==模型名,建議這個屬性爲必填屬性瀏覽器
<form:form commandName="book" action="save-book" method="post"> ... </form>
這個commandName爲book,是與請求「save-book」對應的請求方法中模型數據名同樣的,也就是說須要在請求方法中將數據模型添加到Model對象中,model.addAttribute("book",new Book()),若是不這樣作,頁面就會拋出異常。安全
表單標籤的屬性:服務器
屬性 | 描述 |
acceptCharset | 定義服務器接受的字符編碼列表 |
commandName | 暴露表單對象的模型數據名,默認名爲command |
cssClass | 定義要應用到被渲染form元素的CSS類 |
cssStyle | 定義要應用到被渲染form元素的CSS樣式 |
htmlEscape | 接受true/false,表示被渲染的值是否進行HTML轉義 |
modelAttribute | 暴露表單對象的模型數據名,默認名爲command |
通常來講,還是須要action和method屬性,由於這兩個屬性是HTML屬性,仍是必須的。app
input標籤渲染<input type="text">元素,這個標籤最重要的是path,它將這個輸入字段綁定到表單對象的一個屬性,相似HTML表單的name值。工具
input標籤的屬性:post
屬性 | 描述 |
cssClass | 定義要應用到被渲染input元素的CSS類 |
cssStyle | 定義要應用到被渲染input元素的CSS樣式 |
cssErrorClass | 定義要應用到被渲染input元素的CSS類,若是bound屬性中包含錯誤,則會覆蓋cssClass屬性值 |
htmlEscape | 接受true/false ,表示是否應該對渲染的值進行HTML轉義 |
path | 要綁定的屬性名,做用與HTML中的name值一致 |
input標籤也支持綁定到嵌套對象的屬性(支持屬性的屬性,這種級聯的屬性名),如:
<form:input path="category.id"/>
password標籤渲染<input type="password"/>元素,password標籤與input標籤相似,只不過有一個showPassword屬性:
屬性 | 描述 |
cssClass | 定義要應用到被渲染input元素的CSS類 |
cssStyle | 定義要應用到被渲染input元素的CSS樣式 |
cssErrorClass | 定義要應用到被渲染input元素的CSS類,若是bound屬性中包含錯誤,則會覆蓋cssClass屬性值 |
htmlEscape | 接受true/false ,表示是否應該對渲染的值進行HTML轉義 |
path | 要綁定的屬性名,做用與HTML中的name值一致 |
showPassword | 表示是否應該顯示密碼,默認爲false |
hidden標籤渲染<input type="hidden"/>元素,hidden標籤,hidden標籤與input標籤類似,只不過它沒有可視的外觀,以此不支持cssClass和cssStyle屬性
屬性 | 描述 |
htmlEscape | 接受true/false ,表示是否應該對渲染的值進行HTML轉義 |
path | 要綁定的屬性名,做用與HTML中的name值一致 |
textarea標籤渲染一個HTML的textarea元素,Textarea實際就是一個支持多行輸入的一個input元素
屬性值同input相似,咱們還能夠經過rows(行),cols(列)設置textarea的大小:
<form:textarea path="note" rows="5" cols="80"/>
checkbox標籤 checkboxs標籤 radioButton標籤 radioButtons標籤
這些標籤的屬性都與input相似,path屬性較爲重要,可是後面帶s的複數形式是有些區別的:
帶s多個標籤的特有的屬性:
屬性 | 標籤 |
items | 用於生成Collection,Map或者Array數據 |
itemLabel | item屬性中定義的Collection,Map或者Array中對象屬性,爲每一個輸入項提供標籤名 |
iteamsValue | item屬性中定義的Collection,Map或者Array中對象屬性,爲每一個輸入項提供值 |
delimiter | 定義兩個input元素之間的分隔符,默認沒有分隔符 |
element | 給每一個被渲染的input元素都定義一個HTML元素,默認爲「span」 |
例如:
<form:checkbox path="outOfStock" value="Out of Stock"> <form:checkboxs path="category" items="${categoryList}"> Computing Now <form:radiobutton path="newsletter" value="Computing Now"/> Modern Health<form:radiobutton path="mewsletter" value="Modern Health"> <form:radiobuttons path="category" items="${categoryList}"/>
select標籤渲染一個HTML的select元素。被渲染元素的選項可能來自賦予其items屬性的一個Collection,Map,Array,或者來自一個嵌套的option或者options標籤。
屬性值同上checkboxbutton/radiobutton同樣。items對於select或後面加s的標籤特別有用,由於它能夠綁定帶對象的Collection,Map,Array,爲select元素生成選項(option)
<form:select id="category" path="category.id" items="${categories}" itemLabel="name" itemValue="id">
id和name都是categories集合中category對象的屬性
<form:select id="category" path="category.id" items="${categories}" itemLabel="name" itemValue="id"> <option value="0">--Please select--</option> </form:select>
這個代碼片斷是渲染一個select元素,其選項來自model屬性catagories,以及option標籤。
同其餘後綴爲s的標籤同樣,options標籤用於生成多個option元素列表
errors標籤用於渲染一個或多個span元素,每一個span元素中都包括一個字段錯誤信息。這個標籤用於顯示一個特定的字段錯誤,或者全部的字段錯誤
下面這個erros標籤將顯示全部錯誤(全部綁定在BindingResult中的錯誤)
<form:errors path="*"/>
下面這個errors標籤顯示了一個與表單支持對象的author屬性相關的字段錯誤
<form:errors path="author"/>
@RequestMapping("/input-book") public String inputBook(Model model) { List<Category> categories=bookService.getAllCategories(); model.addAttribute("categories", categories); model.addAttribute("book", new Book()); return "bookAddForm"; }
注意: model.addAttribute("book", new Book()); 雖然放入的一個new出來的空對象,可是由於spring表單須要尋在commandName屬性值,爲了避免讓其找不到而報異常因此須要如此。
<c:url var="url" value="/emp"></c:url> <form:form commandName="employee" action="${url }" method="POST">
咱們不容許用戶修改某些字段,可是這樣從修改表單傳過來的表單數據就會沒有這幾項,若是就這樣去修改數據庫,這幾項的數據就會被置空,這明顯不是咱們想要的,咱們想讓這樣不能修改的值保持原樣,應該怎麼作呢?
一個辦法就是使用隱藏域,將這些不能修改的值以隱藏域方式,這些值雖然存在,可是直接從網頁上是看不到的,然而聰明的用戶能夠從瀏覽器的開發者工具中找到這些隱藏項,若是這些選項敏感而又須要安全,這種作法就不太好
還有一種辦法就是使用springMVC的@ModelAttribute註解修飾一個會請求的方法,在這個方法中經過id得到該對象,並將這個對象放在Model中,由於@ModelAttribute修飾的方法在每一個請求方法前會被調用,因此在咱們的修改update方法的形參再使用@ModelAttribute來得到這個實例,springMVC在得到表單輸入的數據進行封裝時,會將你修改的字段封裝,因此也不用擔憂修改的字段值丟失:
@ModelAttribute public void getThisBook(@RequestParam(value="id",required=false) Integer id,Model model) { if(id==null) { return; } model.addAttribute(bookService.get(id)); } @RequestMapping("/update-book") public String updateBook(@ModelAttribute Book book) { System.out.println(book.getCategory().getId()); System.out.println(bookService.getCategory(book.getCategory().getId())); Category category=bookService.getCategory(book.getCategory().getId()); book.setCategory(category); bookService.update(book); return "redirect:/list-book"; }
注意:由於id這個字段很重要,可是並非每次從表單中傳來的數據都有id,例如添加的時候就沒有id,因此必定要設置爲required=false ,要不讓就會報錯。並且建議使用返回爲void的@ModelAttribute修飾的非請求方法,並在其中判斷id是否爲null