使用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表单标签的声明,以下所示: css

<% @ page language = " java " contentType = " text/html; charset=UTF-8 " pageEncoding = " UTF-8 " %> <% @ taglib prefix = " form " uri = " http://www.springframework.org/tags/form " %> ①引入标签的声明 < html > … ②声明后,在页面中就可使用任意Spring表单标签了 </ html >

    通常状况下,咱们使用“form”做为Spring MVC表单标签的前缀,固然只要愿意,你能够调整为其它的前缀名。在声明好标签引用后,就能够在该JSP文件中使用全部Spring MVC的表单标签了。下面是一个使用<form.:form>表单标签的示例,它将最终生成一个HTML的 form表单:  html

< form.:form > 用户名: < form.:input path ="userName" /> < br > 密 码: < form.:password path ="password" />< br > Email: < form.:input path ="email" />< br > < input type ="submit" value ="注册" name ="testSubmit" /> < input type ="reset" value ="重置" /> </ 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 表单元素标签特殊属性 java

 
目录
说明
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 使用输入组件标签的表单 web

< form.:form > 用户名: < form.:input path ="userName" /> < br > ①单行文件框标签密 码: < form.:password path ="password" />< br > ②密码框标签描 述: < form.:textarea path ="desc" cols ="20" rows ="3" />< br > ③多行文件框标签 < form.:hidden path ="times" /> ④隐藏组件的值 < input type ="submit" value ="注册" name ="testSubmit" /> < input type ="reset" value ="重置" /> </ form.:form >

    正如你看到的,全部表单组件标签都经过path属性绑定表单对象的属性值,它支持级联属性,好比path="user.userName"将调用表单对象getUser.getUserName()绑定表单对象的属性值。这些表单组件标签拥有大多数HTML组件标签的镜像属性,如③处的<form.:textarea>就使用了cols和rows属性设定列数和行数。

以上使用表单标签的页面的对应HTML页面以下所示:spring

< form. id ="command" method ="post" action ="/baobaotao//registerUser.html" > 用户名: < input id ="userName" name ="userName" type ="text" value ="" />< br > 密 码: < input id ="password" name ="password" type ="password" value ="" />< br > 描 述: < textarea id ="desc" name ="desc" rows ="3" cols ="20" ></ textarea >< br > < input id ="times" name ="times" type ="hidden" value ="0" /> < input type ="submit" value ="注册" name ="testSubmit" /> < input type ="reset" value ="重置" /> </ form >

单选框和复选框组件标签
    单选框和复选框组件虽然在HTML中都对应<input>元素标签,但在Spring MVC表单标签中,它们分别对应两个更达意的标签:     数据库

< form.:radiobutton > < form.:checkbox > 。 radiobutton 单选框组件由两个同名的标签组件组成,当表单对象对应属性值和value值相等时,单选框选中。下面是一个表明性别的单选框: < form.:form > 性 别: < form.:radiobutton path ="sex" value ="0" /> < form.:radiobutton path ="sex" value ="1" /> </ form.:form > 当表单对象的sex属性为0时(能够是String、int等能够自动转换为String的类型),所生成的HTML代码以下所示: < form. id ="command" method ="post" action ="/baobaotao//registerUser.html" > 性 别: < input id ="sex1" name ="sex" type ="radio" value ="0" checked ="checked" /> < input id ="sex2" name ="sex" type ="radio" value ="1" /> </ form > 

 

checkbox
    复选框组件标签相对来讲复杂一些,复选框组件对应的表单属性不但能够boolean类型,还能够是String[]、Collection,Enum等类型。针对不一样属性类型,复选框的选中状态的判断条件是不同的:
 boolean类型:当对应属性为true时,该复选框选中(一个属性仅对应一个复选框);
 String[]、Collection或Enum类型:复选框对应值出如今对应属性列表中,该复选框选中;
 其它类型:当复选框对应的值能够转换为对应属性值,该复选框选中。
假设用户注册的User表单对象包含了一个List类型的favorites属性:
import java.util.List;
public class User {
private List favorites;
public List getFavorites() {
return favorites;
}
public void setFavorites(List favorites) {
this.favorites = favorites;
}
}
咱们但愿将其在页面中使用一个复选框组件绑定这个属性,则可使用如下的代码:
代码清单 2 复选框标签的使用
<form.:form>
兴趣爱好:
<form.:checkbox path="favorites" value="1"/>computer
<form.:checkbox path="favorites" value="2"/>sport
<form.:checkbox path="favorites" value="3"/>entertainment
<form.:checkbox path="favorites" value="4"/>literature
</form.:form>
除了正常的path属性名外,还必须提供一个value属性,假设User表单对象的favorites属性包括了1和3的值,那么产生的HTML页面为:
<form. id="command" method="post" action="/baobaotao//registerUser.html">
兴趣爱好:<input id="favorites1" name="favorites" type="checkbox" value="1" checked="checked"/>
<input type="hidden" value="1" name="_favorites"/>computer
<input id="favorites2" name="favorites" type="checkbox" value="2" />
<input type="hidden" value="1" name="_favorites"/>sport
<input id="favorites3" name="favorites" type="checkbox" value="3" checked="checked"/>
<input type="hidden" value="1" name="_favorites"/>entertainment
<input id="favorites4" name="favorites" type="checkbox" value="4"/>
<input type="hidden" value="1" name="_favorites"/>literature
</form>
你们可能已经注意到每一个复选框组件的后台都跟着一个隐藏组件,这是由于当HTML页面中的复选框没有被选中时,这个复选框的值不会在表单提交时做为HTTP请求参数发送到服务器端,这给Spring的表单数据绑定形成了麻烦——由于没法触发setFavorites()方法的调用(若是原来已经有值,这个值不会被设置为空)。解决方法就是在每一个复选框后面加一个隐藏组件,而且将对应的复选框名字前添加一个下划线("_")做为隐藏组件的名字。这样一来,你至关于告诉Spring“这个表单中存在这样一个复选框,我但愿表单对象中对应的属性和这个checkbox的状态保持一致”。
假设复选框对应的选项在数据库或配置文件中定义,那么页面复选框标签就不能经过硬编码的方式指定,相反必须根据配置的选项数据动态产生。对于这样的需求,代码清单 2的编写方式显然不能知足需求。回忆一下表单控制器的工做流程,咱们知道能够经过复写referenceData()方法在表单显示前准备一些须要的数据,如今终于派上用场了,来看一下具体的实现:

代码清单 3 UserRegisterController:准备表单显示数据 服务器

package com.baobaotao.web.user; … import org.springframework.ui.ModelMap; public class UserRegisterController extends SimpleFormController { private BbtForum bbtForum; ①建立初始表单对象 protected Object formBackingObject(HttpServletRequest request) throws Exception { int userId = ServletRequestUtils.getIntParameter(request, " userId " , - 1 ); User user = bbtForum.getUser(userId); user.setUserName( " tom " ); List favorites = new ArrayList();① - 1默认选中值为1和3的选项 favorites.add( " 1 " ); favorites.add( " 3 " ); user.setFavorites(favorites); return user; } @Override ②准备表单显示时须要的数据 protected Map referenceData(HttpServletRequest request) throws Exception { Map favoriteMap = new LinkedHashMap(); favoriteMap.put( " 1 " , " computer " ); favoriteMap.put( " 2 " , " sport " ); favoriteMap.put( " 3 " , " entertainment " ); favoriteMap.put( " 4 " , " literature " ); ② - 1将表单页面须要的对象以ModelMap返回,最终将以属性名值对方式出如今请求属性中 return new ModelMap().addObject( " favoriteMap " , favoriteMap); } @Override protected ModelAndView onSubmit(Object command, BindException errors) throws Exception { User user = (User) command; bbtForum.registerUser(user); return new ModelAndView(getSuccessView(), " user " , user); } }

    在以上代码中咱们覆盖了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并动态构造出复选框列表了:    框架

<% @ page language = " java " contentType = " text/html; charset=UTF-8 " pageEncoding = " UTF-8 " %> <% @ taglib prefix = " form " uri = " http://www.springframework.org/tags/form " %> <% @ taglib uri = " http://java.sun.com/jsp/jstl/core " prefix = " c " %> < html > < head > < title > 宝宝淘论坛用户注册 </ title > </ head > < body > < form.:form > … 兴趣爱好: < c:forEach items = " ${favoriteMap} " var = " favorite " > ①引用favoriteMap的请求属性 ②引用Map的键和值 < form.:checkbox path = " favorites " value = " ${favorite.key} " /> ${favorite.value} </ c:forEach > < input type = " submit " value = " 注册 " name = " testSubmit " /> < input type = " reset " value = " 重置 " /> </ form.:form > </ body > </ 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:为下拉框标签准备数据 jsp

package com.baobaotao.web.user; … public class UserRegisterController extends SimpleFormController { @Override protected Map referenceData(HttpServletRequest request) throws Exception { Map favoriteMap = new LinkedHashMap(); favoriteMap.put( " 1 " , " computer " ); favoriteMap.put( " 2 " , " sport " ); favoriteMap.put( " 3 " , " entertainment " ); favoriteMap.put( " 4 " , " literature " ); List cityList = new ArrayList();①为下拉框选项准备的数据 cityList.add( " 北京 " ); cityList.add( " 上海 " ); cityList.add( " 天津 " ); cityList.add( " 厦门 " ); return new ModelMap() .addObject( " favoriteMap " , favoriteMap) .addObject( " cityList " , cityList); } … } 这时,生成的下拉框HTML代码以下所示: < select id = " city " name = " city " > < option value = " 北京 " > 北京 </ option > < option value = " 上海 " > 上海 </ option > < option value = " 天津 " > 天津 </ option > < option value = " 厦门 " > 厦门 </ option > </ select > < 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", "密码不能为空");

    当提交的表单数据不合法引起校验错误时,提交的表单将被驳回,请求被重定向到表单输入页面,在该页面中经过ide

< form.:errors > 标签就能够显示出校验的错误信息: < form.:form > 用户名: < form.:input path ="userName" cssClass ="inputStyle" cssErrorClass ="asdfe" /> < font color ="red" >< form.:errors path ="userName" /></ font > < br > 密 码: < form.:password path ="password" /> < font color ="red" >< form.:errors path ="password" /></ font > < br > </ form.:form >

    经过path和表单对象特定属性错误信息进行绑定,一个表单对象属性可能包括一个或多个错误信息,也能够没有错误信息,<form.:errors>会根据错误信息的状况进行合理的展现。此外,path还支持通配符匹配的表示方式:
 path="*": 显示全部的错误信息;
 path="lastName*": 显示全部属性名前缀为lastName的错误信息。

小结
    在Spring 2.0中,新增的表单标签是Spring MVC的一个显著的升级,它能够绑定服务端的表单对象,让页面数据的渲染工做变得轻松。由于Spring MVC框架自己的优越性,使得许多Spring MVC表单标签无需进行过多的属性设置就能够正确使用,所以相比于Struts的表单标签,Spring MVC在使用上更加方便,更加轻松。

 转自http://blog.csdn.net/xuantian868/article/details/3076264

相关文章
相关标签/搜索