虽然咱们可使用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