Struts2的输入校验有两种方式:一种是用Action中定义的validate()方法进行校验,一种是用Struts2定义好的校验框架进行校验。前者里面的逻辑判断要自己写,而后者只需要传递相应的参数即可。
不管是哪种方式,程序执行的流程都是一样的,执行流程如下:
1、对表单传递过来的数据,先进行类型转换
2、执行校验
3、若校验不合法,则跳转到以input命名的result页面,若合法,则跳转到指定的页面
下面举例来说明用Action中定义的validate()方法进行校验这种方式(第二种方式在下一篇博客中说明):
这种方法,是在Action中用其中的validate()方法进行校验,如下例:
其中的EMail是自定义的数据类型,要编写类型转换器,进行类型转换,详情看上一篇博客。这里为了更清晰的介绍执行流程,所以加上一个自定义的数据类型的属性。
package com.suo.actions;
import java.util.Calendar;
import java.util.Date;
import com.opensymphony.xwork2.ActionSupport;
import com.suo.beans.EMail;
/**
* 处理用户注册的Action,其中uername,password,birthday,Struts2都提供了内部的类型转换,
* 但是对于自定义的EMail,就要自己编写类型转换的代码,以满足条件。
* @author hackerain
*/
public class RegisterAction extends ActionSupport
{
private String username;
private String password;
private String repassword;
private Date birthday;//Struts2已提供了内部的类型转换器
private int age;
private EMail email;//自定义数据类型,要编写类型转换器,以进行类型转换
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRepassword() {
return repassword;
}
public void setRepassword(String repassword) {
this.repassword = repassword;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public EMail getEmail() {
return email;
}
public void setEmail(EMail email) {
this.email = email;
}
/**
* execute()覆盖父类中的方法,进行总的业务处理
*/
public String execute() throws Exception {
System.out.println(username);
System.out.println(password);
System.out.println(birthday);
System.out.println("age");
System.out.println(email.getFormer());
System.out.println(email.getLatter());
return SUCCESS;
}
/**
* 验证方法,覆盖父类中的validate(),对属性进行验证:
* 用户名介于4——6个字符之间,且不能为空,
* 密码介于4——6个字符之间,且不能为空,
* 两次输入的密码要一致,
* 生日要大于1900-01-01,小于当前日期,
* 邮箱要为qq邮箱、163邮箱、yahoo邮箱三者中的一个。
* 若输入的信息不合法,则会默认跳转到以"input"为命名的<result>页面,进行重新输入。
*/
public void validate() {
if(username==null || username.length()<4 || username.length()>6)
{
this.addActionError("username error !");
}
if(password==null || password.length()<4 || password.length()>6)
{
this.addActionError("password error !");
}
else if(repassword==null || repassword.length()<4 || repassword.length()>6)
{
this.addActionError("repassword error !");
}
else if(!password.equals(repassword))
{
this.addActionError("passwords are different !");
}
if(birthday==null)
{
this.addActionError("birthday is invalid !");
}
else
{
Calendar birthCal=Calendar.getInstance();
birthCal.setTime(birthday);
Date now=new Date();
Calendar upperCal=Calendar.getInstance();
upperCal.setTime(now);
Calendar lowerCal=Calendar.getInstance();
lowerCal.set(1900, 1, 1);
if(!(lowerCal.before(birthCal) && birthCal.before(upperCal)))
{
this.addActionError("birthday should be between 1900-01-01 to now !");
}
}
if(age<10 || age>50)
{
this.addActionError("age should be between 10 and 50");
}
if(email==null)
{
this.addActionError("email is invalid !");
}
else
{
if(!(email.getLatter().equals("qq.com") || email.getLatter().equals("163.com") ||
email.getLatter().equals("yahoo.com.cn")))
{
this.addActionError("email should be among qq.com, 163.com and yahoo.com.cn !");
}
}
//this.clearErrors();
}
}
关于错误信息的处理,有两种方式,一种是addActionError(),另一种是addFieldError(),关于两者的区别,如下:
在校验前,即执行validate()方法前,先要进行类型转换,若类型转换发生错误,则Struts会自动将错误信息放到相应的属性错误字段中,即调用addFieldError()方法,添加到其中的错误信息也是Struts2默认的;然后,调用set方法时,由于类型转换发生错误,所以会找不到对应属性的set方法,从而使得该属性值在Action中为默认值;在校验时,即执行validate()方法时,若有不合法的属性,此时,若指定了添加错误信息的方式,addFieldError()或addActionError(),则只会相应的执行指定的方法,并且会累加,即写了几次该方法,就会添加几次错误信息,因为在底层添加的错误信息是存储在一个ArrayList<String>数组中的,不会覆盖原来的错误信息。
总得来说,在类型转换发生异常是,addFieldError()会由struts2自动调用,而addActionError()是在Action中显示调用的,但是addFieldError()也可以在Action中显示调用。
在发生类型转换异常时,Struts2会自动调用addFieldError(),向ArrayList<String>数组中添加错误信息,但是添加的错误信息是Struts2默认的:Invalid field value for field "xxx",其实也可以自己定义字段级别的错误信息,方法如下:
1、在该Action所在的包中,添加一个以该Action的类名为文件名的properties文件。
2、在其中指定key和value
key有固定的格式:invalid.fieldvalue. + Action中要检验的属性名,如:invalid.fieldvalue.username;
value就是自己定义的错误信息了。
注意,若自定义的错误信息是中文的话,则应选择Properties模式,进行编辑,因为中文是以UNICODE进行表示的。
如本例中的自定义错误信息的properties文件名为:RegisterAction.properties,内容为:
invalid.fieldvalue.username=\u7528\u6237\u540D\u4E0D\u5408\u6CD5
invalid.fieldvalue.password=\u5BC6\u7801\u4E0D\u5408\u6CD5
invalid.fieldvalue.birthday=\u751F\u65E5\u4E0D\u5408\u6CD5
invalid.fieldvalue.age=age should be between 10 and 50
invalid.fieldvalue.email=\u90AE\u7BB1\u4E0D\u5408\u6CD5
age属性的错误信息是用英文写的,其他的属性是用中文写的,在源代码模式下,显示的就是中文的ascii编码