数据绑定概述
数据绑定是将用户输入的绑定到领域模型的一种特性。 有了数据绑定,类型总是为String的HTTP请求参数,可用于填充不同类型的对象属性。 数据绑定使得form bean(前几篇博文中的ProductForm实例)变成多余。
为了更高效的使用数据绑定,还需要Spring的表单标签库,本篇博文着重讲解数据绑定和表单标签库。
基于HTTP的特性,所有HTTP请求参数的类型均为字符串。 我们前面的示例中,为了获取正确的产品价格,不得不将字符串解析为float类型。
我们来回顾下之前的代码
@RequestMapping(value = "/product_save", method = RequestMethod.POST) public String saveProduct(ProductForm productForm, Model model) { logger.info("saveProduct called ...."); // no need to create and instantiate a ProductForm // create Product Product product = new Product(); product.setName(productForm.getName()); product.setDescription(productForm.getDescription()); try { product.setPrice(Float.parseFloat(productForm.getPrice())); } catch (NumberFormatException e) { } ........ ........ }
之所以要解析productForm中的price属性,是因为它是一个String,却需要用float来填充Product的price属性。 有了数据绑定,就可以用下面的代码取代上面的saveProduct方法
@RequestMapping(value = "/product_save", method = RequestMethod.POST) public String saveProduct(Product Product , Model model) { ... ... }
注意第一个入参变为了Product,有了数据绑定就不需要ProductForm类了,也不需要解析Product对象的price属性了。
数据绑定的另外一个好处是:当输入验证失败时,它会重新生成一个HTML表单,手工编写html代码时,必须记住用户之前的输入值,重新填充输入字段, 有了Spring的数据绑定和表单标签库后,这些工作它们将替你完成。
表单标签库
标签库概述
表单标签库中包含了可以用在JSP页面中渲染HTML元素的标签,为了使用这些标签,必须在JSP页面的开头处声明这个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 | 渲染textarea元素 |
checkbox | 渲染一个 <input type="checkbox"> 元素 |
checkboxes | 渲染多个 <input type="checkbox"> 元素 |
radiobutton | 渲染一个 <input type="radio"> 元素 |
radiobuttons | 渲染多个 <input type="radio"> 元素 |
select | 渲染一个选择元素 |
option | 渲染一个可选元素 |
options | 渲染一个可选元素列表 |
errors | 在span元素中渲染字段错误 |
form表单标签
表单标签用于渲染HTML表单。 表单标签必须利用渲染表单输入字段的其他任意标签。
如下表单标签属性,没有包括html属性,比如method和action
属性 | 描述 |
acceptCharset | 定义服务器接收的字符编码列表 |
commandName | 暴漏表单对象之模型属性的名称,默认为command |
cssClass | 定义要应用到被渲染form元素的css类 |
cssStyle | 定义要应用到被渲染form元素的css样式 |
htmlEscape | 接收true或者false,表示被渲染的值是否应该进行HTML转义 |
modelAttribute | 暴漏form backing object的模型属性名称,默认为command |
commandName属性或许是其中最重要的属性,因为它定义了模型属性的名称,其中包含了一个backing object, 其属性将用于填充所生成的表单。 如果该属性存在,则必须在返回包含该表单的视图的请求处理方法中添加对应的模型属性。
举个例子: ArtisanAddForm.jsp
<form:form commandName="artisan" action="artisan_save" method="post"> ...... ...... </form:form>
ArtisanController类中的 inputArtisan方法,是返回ArtisanAddForm.jsp的请求处理方法,下面是inputArtisan方法
@RequestMapping(value="/artisan_input") public String inputArtisan(Model model){ ....... ....... model.addAttribute("artisan",new Artisan); return "ArtisanAddForm"; }
此处用artisan属性创建了一个Artisan对象,并添加到Model中。 如果没有Model属性,ArtisanAddForm.jsp页面就会抛出异常,因为表单标签无法找到在其commandName属性中指定的form backing object.
此外, 一般来说,仍然需要使用action和method属性,这两个属性是HTML属性,因此不在我们的上述列表中。
input标签
input标签渲染<input type="text"/>
元素。 最重要的属性是path, 它将这个输入字段绑定到form backing object的一个属性
比如,若form标签的commandName属性为artisan, 并且input标签的属性为nickName, 那么input标签将被绑定到Atrtisan对象的nickName属性上.
属性 | 描述 |
path | 要绑定的属性路径 |
cssClass | 定义要应用到被渲染form元素的css类 |
cssStyle | 定义要应用到被渲染form元素的css样式 |
htmlEscape | 接收true或者false,表示被渲染的值是否应该进行HTML转义 |
cssErrorClass | 定义要应用到渲染input元素的css类,如果bound属性中包含错误,则覆盖cssClass属性值 |
举个例子,下面这个input标签被绑定到form backing object的 nickName属性
<form:input id="nickName" path="nickName" cssErrorClass="errorBox"/>
它将会被渲染成下面的</input>
元素
<input type="text" id="nickName" name="nickName"/>
cssErrorClass属性不起作用,除非nickName属性中有输入错误的校验,并且采用同一个表单重新显示用户输入,在这种情况下,input标签会被渲染成下面这个input元素
<input type="text" id="nickName" name="nickName" class="errorBox"/>
input标签也可以绑定到嵌套对象的属性,例如,下面这个input标签绑定到form backing object的category属性的id属性
<form:input id="nickName" path="category.id" />
password
password 标签渲染<input type="password"/>
元素,属性与input相似,只不过它有个showPassword属性
属性 | 描述 |
path | 要绑定的属性路径 |
cssClass | 定义要应用到被渲染form元素的css类 |
cssStyle | 定义要应用到被渲染form元素的css样式 |
cssErrorClass | 定义要应用到渲染input元素的css类,如果bound属性中包含错误,则覆盖cssClass属性值 |
htmlEscape | 接收true或者false,表示被渲染的值是否应该进行HTML转义 |
showPassword | 表示应该显示或者遮盖密码,默认false |
<form:password path = "password" />
hidden
hidden标签渲染 <input type="hidden"/>
元素,与input标签元素相似,只不过它没有可视的外观,因此不支持cssClass和cssStyle.
属性 | 描述 |
path | 要绑定的属性路径 |
htmlEscape | 接收true或者false,表示被渲染的值是否应该进行HTML转义 |
比如
<form:hidden path = "id" />
textarea
textarea标签渲染一个HTML的textarea。 支持多行输入的input元素
属性 | 描述 |
path | 要绑定的属性路径 |
cssClass | 定义要应用到被渲染form元素的css类 |
cssStyle | 定义要应用到被渲染form元素的css样式 |
htmlEscape | 接收true或者false,表示被渲染的值是否应该进行HTML转义 |
cssErrorClass | 定义要应用到渲染input元素的css类,如果bound属性中包含错误,则覆盖cssClass属性值 |
<form:textarea path="comment" tabindex="4" rows="5" cols="80"/>
checkbox标签
hidden标签渲染 <input type="checkbox"/>
元素
属性 | 描述 |
path | 要绑定的属性路径 |
cssClass | 定义要应用到被渲染form元素的css类 |
cssStyle | 定义要应用到被渲染form元素的css样式 |
htmlEscape | 接收true或者false,表示被渲染的值是否应该进行HTML转义 |
cssErrorClass | 定义要应用到渲染input元素的css类,如果bound属性中包含错误,则覆盖cssClass属性值 |
label | 要作为label用于被渲染复选框的值 |
<form:checkbox path="outofStock" value="out of stock"/>
radiobutton
radiobutton标签渲染 <input type="radio"/>
元素
属性 | 描述 |
path | 要绑定的属性路径 |
cssClass | 定义要应用到被渲染form元素的css类 |
cssStyle | 定义要应用到被渲染form元素的css样式 |
cssErrorClass | 定义要应用到渲染input元素的css类,如果bound属性中包含错误,则覆盖cssClass属性值 |
htmlEscape | 接收true或者false,表示被渲染的值是否应该进行HTML转义 |
label | 要作为label用于被渲染复选框的值 |
<form:radiobutton path = "gender" value = "M" label = "Male" /> <form:radiobutton path = "gender" value = "F" label = "Female" />
checkboxes
checkboxes 标签渲染多个<input type="checkbox"/>
元素
<form:checkboxes items = "${frameworkList}" path = "favoriteFrameworks" />
radiobuttons
radiobuttons标签渲染多个<input type="radio"/>
元素
<form:radiobuttons path = "favoriteFood" items = "${foodList}" />
select
select标签渲染一个HTML的select元素。 被渲染元素的选项可能来自赋予items属性的一个Collection、Map、Array ,或者来自一个嵌套的option或者options标签。
属性 | 描述 |
path | 要绑定的属性路径 |
cssClass | 定义要应用到被渲染form元素的css类 |
cssStyle | 定义要应用到被渲染form元素的css样式 |
cssErrorClass | 定义要应用到渲染input元素的css类,如果bound属性中包含错误,则覆盖cssClass属性值 |
htmlEscape | 接收true或者false,表示被渲染的值是否应该进行HTML转义 |
items | 用于生成input元素的对象的Collection、Map、Array |
itemLabel | item属性中定义的Collection、Map、Array中的对象属性,为每个input元素提供lable |
itemValue | item属性中定义的Collection、Map、Array中的对象属性,为每个input元素提供值 |
最重要的属性是 items, 因为它可以绑定到对象的Collection、Map、Array,为select元素生成选项
比如,下面的select标签绑定到form backing object的category属性的id属性。 它的选项来自model属性categories。 每个选项的值均来自 categories collection/map/array的id属性,它的lable来自name属性。
<form:select id="category" path="category.id" items="${categories}" itemsLabel="name" itemValue="id"/>
option
option标签渲染select元素中用的一个HTML的option元素
属性 | 描述 |
cssClass | 定义要应用到被渲染form元素的css类 |
cssStyle | 定义要应用到被渲染form元素的css样式 |
cssErrorClass | 定义要应用到渲染input元素的css类,如果bound属性中包含错误,则覆盖cssClass属性值 |
htmlEscape | 接收true或者false,表示被渲染的值是否应该进行HTML转义 |
<form:select id="category" path="category.id" items="${categories}" itemsLabel="name" itemValue="id"> <option value="0">-- Please select --</option> </form:select>
这个代码段是渲染一个select元素,其选项来自model属性categories, 以及options标签
options
options标签生成一个HTML的option元素列表
属性 | 描述 |
cssClass | 定义要应用到被渲染form元素的css类 |
cssStyle | 定义要应用到被渲染form元素的css样式 |
cssErrorClass | 定义要应用到渲染input元素的css类,如果bound属性中包含错误,则覆盖cssClass属性值 |
htmlEscape | 接收true或者false,表示被渲染的值是否应该进行HTML转义 |
items | 用于生成input元素的对象的Collection、Map、Array |
itemLabel | item属性中定义的Collection、Map、Array中的对象属性,为每个input元素提供lable |
itemValue | item属性中定义的Collection、Map、Array中的对象属性,为每个input元素提供值 |
errors
erros标签渲染一个或者多个HTML的span元素,每个span元素中包含一个字段错误。这个标签可以用于显示一个特定的字段错误,或者所有字段错误。
属性 | 描述 |
cssClass | 定义要应用到被渲染form元素的css类 |
cssStyle | 定义要应用到被渲染form元素的css样式 |
htmlEscape | 接收true或者false,表示被渲染的值是否应该进行HTML转义 |
delimiter | 分割多个错误消息的分隔符 |
element | 定义一个包含错误消息的HTML元素 |
path | 要绑定的错误对象路径 |
比如显示所有的字段错误
<form:errors path="*">
显示一个与form backing object的author属性相关的字段错误
<form:errors path="author">
源码
代码已提交到github
https://github.com/yangshangwei/SpringMvcTutorialArtisan