随笔-179  评论-666  文章-29  trackbacks-0

概述
    在低版本的spring中,你必须通过jstl或将表单对象绑定到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标签
    和使用任何jsp扩展标签一样,在使用spring表单标签之前,你必须在jsp页面中添加一行引用spring表单标签的声明,如下所示:
<%@ 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的表单标签了。下面是一个使用表单标签的示例,它将最终生成一个html的 form表单:  
<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请求调用表单控制器时,表单控制器生成一个新的表单对象,然后重定向到表单输入页面。正因为表单页面是通过访问表单控制器导向过来的,所以标签本身无需做额外的设置就可以达到以下两个目标:
    1) 它不需要象html的标签或struts的表单标签一样通过action属性指定表单提交的地址。假设和标签对应的控制器的url是“/registeruser.html”,应用部署目录为“baobaotao”,则最后产生的html代码自动包含表单提交地址:

    2) 标签内部的组件标签(如等)可以直接和表单控制器所对应的表单对象进行值绑定。

    默认情况下,表单控制器将表单对象以“command”为名放到pagecontext中,你可以通过表单控制器commandname属性的设置使用其它的名字(假设设置为“user”),这时你必须通过显式指定绑定的表单对象名称。

    除了commandname属性外,spring表单标签拥有丰富的可设置属性,这些属性大都是html表单标签属性的镜像,如onclick、ondblclick、tabindex等等。需要注意的一点是这些属性都是小写的,而对应的html标签的属性则没有这个限制。但是有几个和html标签有区别的属性,我们通过表 1进行说明:
    表 1 表单元素标签特殊属性
目录
说明
cssclass
使用该属性指定表单元素css样式名,相当于html元素的class属性。示例:
cssstyle
直接通过该属性指定样式,相当于html元素的style属性。示例:
csserrorclass
cssclass表示表单元素未发生错误时对应的样式,而csserrorclass表示表单元素发生错误时对应的样式,示例:
输入组件标签
    表单中有一些用于接受输入值的组件,如单行文本框、多行文本框以及密码框,spring为它们提供了对应的表单标签,请看下面的例子:
代码清单 1 使用输入组件标签的表单
<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组件标签的镜像属性,如③处的就使用了cols和rows属性设定列数和行数。

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

<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中都对应元素标签,但在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 复选框标签的使用

兴趣爱好:
computer
sport
entertainment
literature

除了正常的path属性名外,还必须提供一个value属性,假设user表单对象的favorites属性包括了1和3的值,那么产生的html页面为:

兴趣爱好:
computer

sport

entertainment

literature

大家可能已经注意到每个复选框组件的后台都跟着一个隐藏组件,这是因为当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返回,最终将以属性名值对方式出现在请求属性中 returnnew modelmap().addobject("favoritemap", favoritemap); } @override protected modelandview onsubmit(object command, bindexception errors) throws exception { user user = (user) command; bbtforum.registeruser(user); returnnew modelandview(getsuccessview(), "user", user); } }

   

posted on 2009-06-26 11:01 alpha 阅读(23881) 评论(4)     所属分类: spring

评论:
# re: 使用spring mvc表单标签 2013-08-20 11:57 |
ttt  回复  
  
# re: 使用spring mvc表单标签 2013-08-20 11:58 |
oo  回复  
  
# re: 使用spring mvc表单标签 2014-05-16 21:30 |
最代码转载地址:  回复  
  
# re: 使用spring mvc表单标签 2016-05-18 20:24 |
水电费  回复  
  

只有注册用户后才能发表评论。


网站导航:
              
 
网站地图