之前我们在写Action类的时候会继承ActionSupport类,ActionSupport类会为我们提供一些辅助的功能。其中的validate()方法就是从ActionSupport中继承的,但是实际上这个方法是为空的,需要我们自己实现来进行实际的校验。
1)在校验正确通过时,程序会寻找对应Action中result为success的页面,然后跳转。
2)在校验不正确或者类型转换不正确时,我们要求的是返回原页面。那程序会寻找对应Action中result为input的页面,然后跳转到原页面。input对应的含义是,当用户的输入不合法时,应该再次提供输入。
3)借助struts2的标签库,将准确的错误信息在页面上显示。
具体的流程如下:
1)编写注册页面register.jsp
<body>
<h2>用户注册</h2>
<form action="register">
<span style="color:#ff0000;"><s:actionerror/></span>//显示对应的错误信息
username:<input type="text" name="username"><br>
password:<input type="password" name="password"><br>
repassword:<input type="password" name="repassword"><br>
age:<input type="text" name="age"><br>
birthday:<input type="text" name="birthday"><br>
graduate:<input type="text" name="graduate"><br>
<input type="submit" value="submit">
</form>
</body>
2)编写对应的action类
public class RegisterAction extends ActionSupport {
private String username;
private String password;
private String repassword;
private int age;
private Date birthday;
private Date graduate;
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Date getGraduate() {
return graduate;
}
public void setGraduate(Date graduate) {
this.graduate = graduate;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return SUCCESS;
}
@Override//效验部分可以在不校验上跑通后再实现
<span style="color:#ff0000;">public void validate() {
// TODO Auto-generated method stub
System.out.println("validate()");
if(null==username||username.length()<4||username.length()>6)
{
this.addActionError("用户名无效");
}
if(null==password||password.length()<4||password.length()>6)
{
this.addActionError("密码无效");
}else if(null==repassword||repassword.length()!=password.length())
{
this.addActionError("密码长度不一致");
}else if(repassword.equals(password))
{
this.addActionError("密码不一致");
}
if(age<10||age>50)
{
this.addActionError("年龄无效");
}
if(null==birthday)
{
this.addActionError("出生日期为空");
}
if(null==graduate)
{
this.addActionError("毕业日期为空");
}
if(null==graduate&&null==birthday)
{
Calendar c1=Calendar.getInstance();
c1.setTime(birthday);
Calendar c2=Calendar.getInstance();
c2.setTime(graduate);
if(!c1.before(c2))
{
this.addActionError("毕业日期出生日期不匹配");
}
}</span>
}
}
3、在struts.xml中配置Action
<action name="register" class="cn.sict.register.RegisterAction">
<result name="success">/registerResult.jsp</result>
<result name="input">/register.jsp</result>//输入校验不通过时,再次返回register页面</span>
</action>
4、在registerResult.jsp中显示结果,注意添加struts2的标签库
<body>
username:<s:property value="username"/><br>
password:<s:property value="password"/><br>
age:<s:property value="age"/><br>
birthday:<s:property value="birthday"/><br>
graduate:<s:property value="graduate"/><br>
</body>
</html>
通过上述代码的实现,程序的执行如下,1)首先进行类型转换,如果输入的类型无法进行正确转换,对应的set方法将不会执行,抛出异常。2)然后对输入进行校验。3)如果出现了类型转换错误和校验错误,都不会去执行execute方法,会转向struts.xml中该action的名为input的result所对应的页面。
ActionSupport类的addActionError()方法会将错误的消息添加到ArrayList对象中。当调用getActionErrors()方法时,返回的实际是一个集合的副本而不是集合的本身,因此对集合副本调用clear()方法清除元素,对原集合元素没有任何影响。可以通过clearActionError()方法,对list中的错误信息进行清除。
我们看到这种错误显示的方法在可能出现很多错误时不人性化,我们希望在每个文本框的后面显示对应的错误信息。
使用FieldError 形式如 this.addFieldError("username","用户名无效");可以得到对应信息的准确信息。FieldError的底层是用LinkedHashMap实现的,该Map的key是String类型,value是List<String>类型。
还有一种情况,当在age、birthday、graduate中输入了无法转换的字符类型时,在页面上打印<s:fielderror/>标签内容时,会出现如下的提示。
这就是类型转换的时候出现错误,它会自动添加到FieldError中,但是以上的提示不够人性,我们可以对应的字段,发生类型转换时,自定义错误信息。
步骤如下:1)新建一个以action命名的properties文件,如RegisterAction.properties文件。
2)在该属性文件中指定每一个出错字段的错误信息。如nvalid.fieldvalue.age=age invalid
配置之后显示如下:
那如果希望提示的信息是中文的呢?我使用的eclipse版本是当输入中文字符时,敲回车自动转换为unicode字符。如果不具有这个功能,可以在jdk的bin文件下找到一个native2ascii的exe文件,通过它将中文转化为Unicode符就可以显示了。