使用struts框架获取到数据后,需要在action中取出这些formbean数据并将其封装到实体数据中去。封装到实体数据中去,可以使用beanUtils工具,但是这个工具不能自动将日期字符串转换java.utils.Date类型(ConveterUtils中维护的所有转换器有能将String类型转换成java.sql.Date类型的日期)及枚举等类型。因此还需要开发者针对自己定义的数据类型,添加一些转换器。这些转化器可以添加到一个监听器上,因此开发者可以通过监听ServletContext的创建,来添加这些监听器,这样在使用beanUtils时,可以使用注册的转换器对该类型进行转换。
调用ConvertUtils的register方法能将注册的转换器添加到convertUtilsBean中的converters属性中,它是一个Map,维护了一些转换器。添加一个转换器的示例如下:
// 注册转换日期的转换器
ConvertUtils.register(new Converter() {
public Object convert(Class type, Object value) {
if (value == null) {
return null;
}
if (value instanceof String) {
String d = (String) value;
if (d.trim().equals("")) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
return sdf.parse(d);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
throw new RuntimeException("输入类的类型不是String");
}
}, Date.class);
// 转性别枚举
ConvertUtils.register(new Converter() {
public Object convert(Class type, Object value) {
if (value == null) {
return null;
}
return Gender.valueOf(((String) value).toUpperCase());
}
}, Gender.class);
此转化器可以放在servletContext被创建时注册。这样,当注册了这些转换器后,在action中调用BeanUtils.copyProperties可以将formBean中的值注册到User实体中。如下代码:
User user = new User();
BeanUtils.copyProperties(user, tfb);
System.out.println(user.getBirthday());
考虑到当validator属性配置为true时,在由action处理时,已经对FormBean属性中的Date或枚举类型(用户自定义的类型)进行了校验,因此应该尽量不需要在action中在此处理。是用的方法是在用户定义的FormBean类中,添加一个实体对象,并生成其get和set方法。当每个属性在validator时,每校验过一个,便将此属性值赋给user对象。如下:
@Override
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
//用户名不能为空,并且要是3-8位的字母
if(isEmpty(this.username)){
addMessage(errors, "username", "用户名不能为空");
}else{
if(!this.username.matches("[A-Za-z]{3,9}")){
addMessage(errors,"username", "用户名必须是3-8位字母");
}
user.setUsername(this.username);
}
//密码不能为空,要是3-9的字母或数字
if(isEmpty(this.password)){
addMessage(errors, "password", "密码不能为空");
}else{
if(!this.password.matches("\\w{3,9}")){
addMessage(errors,"password", "密码必须是3-8位字母或数字");
}
user.setPassword(password);
}
//性别不能为空,并且要是枚举的一个实例的值
if(isEmpty(this.gender)){
addMessage(errors, "gender", "性别不能为空");
}else{
try{
Gender g = Gender.valueOf(this.gender.toUpperCase());
user.setGender(g);
}catch (Exception e) {
addMessage(errors, "gender", "性别非法");
}
}
//生日可以为空,不为空时,要是一个日期
if(!isEmpty(this.birthday)){
try{
DateLocaleConverter conver = new DateLocaleConverter();
Date d = (Date) conver.convert(this.birthday);
user.setBirthday(d);
}catch (Exception e) {
addMessage(errors, "birthday", "生日不能一个合法的日期");
}
}
//邮箱可以为空,不为空时,要是一个格式有效的邮箱
if(!isEmpty(this.email)){
if(!this.email.matches("\\w+@\\w+(\\.\\w+)+")){
addMessage(errors, "email", "邮箱格式非法");
}
user.setEmail(email);
}
return errors;
}
这样在action,可以直接获取其user属性来封装User实体对象,这样可以不适用beanUtils方法,而起性能更好:具体代码如下:
User user = new User();
user = ufb.getUser();
上面两中方法都可以解决将formBean属性注入到User实体中,但是都有一个缺点,就是需要在action中在进行设置一次。下面的方法是直接通过strust利用BeanUtils对用户请求的数据进行封装到formBean中(前提是不需要对其进行校验)。 BeanUtils支持下面这种设置方式:即对某个对象的某个属性进行设置,下面这个例子将会调用User对象的setUsername属性设置User的username属性。
UserFormBean2 bean = new UserFormBean2();
BeanUtils.setProperty(bean, "user.username", "aaa");
System.out.println(bean.getUser().getUsername());
因此FormBean可以定义成如下形式:
public class UserFormBean2 extends ActionForm {
private User user = new User();
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
jsp页面可以定义成:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>注册页面</title>
</head>
<body>
<html:form action="/Register" >
用户名: <html:text property="user.username" />
<html:errors property="user.username" /> <br />
密码: <html:password property="user.password" redisplay="false"/>
<html:errors property="user.password" /><br />
性别: <c:forEach var="g" items="<%=Gender.values() %>">
<html:radio property="user.gender" value="${g.name }" />${g.value }
</c:forEach>
<html:errors property="user.gender" /> <br />
邮箱: <html:text property="user.emails" />
<html:errors property="user.emails" /> <br />
生日: <html:text property="user.birthday"/>
<html:errors property="user.birthday" /><br />
<html:submit value="注册" /><html:reset value="清空" />
</html:form>
</body>
</html>
当然用这种方法是,首先需要定义BeanUtils不支持的相关类型转换器,如本例中的Date和Gender方法(在servletContext创建时注册)