struts2提供了对所有的方法进行校验和指定的方法的校验,解决了struts1的一个大问题
校验的流程:
1。类型转换器对请求参数执行类型转换,并把转换后的值赋给action中的属性。
2。如果在执行类型转换的过程中出现异常,系统会将异常信息保存到ActionContext,conversionError拦截器将异常信息添加到fieldErrors里。不管类型转换是否出现异常,都会进入第3步。
3。系统通过反射技术先调用action中的validateXxx()方法,Xxx为方法名。
4。再调用action中的validate()方法。
5。经过上面4步,如果系统中的fieldErrors存在错误信息(即存放错误信息的集合的size大于0),系统自动将请求转发至名称为input的视图。如果系统中的fieldErrors没有任何错误信息,系统将执行action中的处理方法。
struts2提供了两种方式进行校验:手工方式和xml方式
一,手工方式
1,对于validate方式的验证,要在struts的配置文件中,配置<resultname=”input” >/login.jsp</result>
<package name="validator" namespace="/validator"extends="struts-default">
<action name="loginAction_*" class="hwt.action.ValidatorAction" method="{1}">
<!—记得要配置这个错误的输出页面,不然会报错-->
<result name="input">/login.jsp</result>
<result name="ok">/show.jsp</result>
</action>
</package>
Action中:
//需要继承ActionSupport,才能实现alidator的验证功能
public class ValidatorAction extends ActionSupport {
private String username;
private String tel;
public String login(){
ActionContext.getContext().put("msg", "login success");
return "ok";
}
public String regist(){
ActionContext.getContext().put("msg", "registe success");
return "ok";
}
//======对所有的方式进行校验
public void validate () {
if(username == null || "".equals(username)){
this.addFieldError("username", "用户名不能为空");
}else if(tel == null || "".equals(tel)){
this.addFieldError("tel", "电话号码不能为空");
}else if(!Pattern.compile("^1[358]\\d{9}$").matcher(tel).matches()){
this.addFieldError("tel", "电话号码的格式不对");
}
}
//======对指定的方式进行校验
public void validateLogin() {
if(username == null || "".equals(username)){
this.addFieldError("username", "用户名不能为空");
}else if(tel == null || "".equals(tel)){
this.addFieldError("tel", "电话号码不能为空");
}else if(!Pattern.compile("^1[358]\\d{9}$").matcher(tel).matches()){
this.addFieldError("tel", "电话号码的格式不对");
}
}
//setter getter方法。。。
}
重写ActionSupport的validate方法,对Action中所有的方法进行校验,要对指定的方法进行校验,那么就只要validateXxx() xxx为要验证的方法的名字,第一个字母大写,但是不管是否通过validateXxx(),最后还是都得经过validate()方法,通过判断fieldError是否有错误,如果有就不会进入方法,而是到指定的input的路径输出错误信息
<%@ taglib prefix="s" uri="/struts-tags"%>
<body>
<form action="${pageContext.request.contextPath }/validator/loginAction_login.action" method="post">
<input type="text" name="username"value="${username }"/>
<s:fielderror fieldName="username"/><br/>
<input type="text" name="tel"value="${tel }"/>
<s:fielderror fieldName="tel"/><br/>
<Input type="submit" value="登录"/>
</form>
</body>
2,xml方式的验证
xml方式的校验和手工代码校验相比,其他地方都不要改,只是在Action中不需要写validate的方法,而是通过配置xml文件来实现校验:
首先,在action类中同样需要继承ActionSupport 和strust.xml中配置<result name=”input”> </result>
·如果要对Action中的所有的方法进行校验的话,那么就需要在Action所在的类下面建立一个ActionClassName-validation.xml,以上例为例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd">
<validators>
<field name="username">
<field-validator type="requiredstring">
<message>用户名不能为空</message>
</field-validator>
</field>
<field name="tel">
<field-validator type="requiredstring">
<message>手机号码不能为空</message>
</field-validator>
<!-- 正则表达式的验证器-->
<field-validator type="regex">
<param name="expression"><![CDATA[^1[358]\\d{9}$]]></param>
<message>手机号码格式不对</message>
</field-validator>
</field>
</validators>
·如果要给Action中指定的方法进行校验的话,那么只需要建立一个ActionClassName-ActionName-validation.xml,内容和上面是完全一样的,
ActionName为struts.xml中action的名称。例如:在实际应用中,常有以下配置:
<action name="user_*" class="cn.hwt.action.UserAction"method="{1}“ >
<result name="success">/WEB-INF/page/message.jsp</result>
<result name="input">/WEB-INF/page/addUser.jsp</result>
</action>
UserAction中有以下两个处理方法:
public String add() throws Exception{
....
}
public String update() throws Exception{
....
}
要对add()方法实施验证,校验文件的取名为: UserAction-user_add-validation.xml
要对update()方法实施验证,校验文件的取名为: UserAction-user_update-validation.xml
当为某个action提供了ActionClassName-validation.xml和ActionClassName-ActionName-validation.xml两种规则的校验文件时,系统按下面顺序寻找校验文件:
1。AconClassName-validation.xml
2。ActionClassName-ActionName-validation.xml
系统寻找到第一个校验文件时还会继续搜索后面的校验文件,当搜索到所有校验文件时,会把校验文件里的所有校验规则汇总,然后全部应用于action方法的校验。如果两个校验文件中指定的校验规则冲突,则只使用后面文件中的校验规则。
当action继承了另一个action,父类action的校验文件会先被搜索到。
假设UserAction继承BaseAction:
<action name="user" class="cn.itcast.action.UserAction"method="{1}">
</action>
当要访问上面action,系统先搜索父类的校验文件:BaseAction-validation.xml, BaseAction-user-validation.xml,接着搜索子类的校验文件: UserAction-validation.xml, UserAction-user-validation.xml。应用于上面action的校验规则为这四个文件的总和。