validator框架总结
validator框架能够克服在ActionForm Bean中以编程方式进行数据验证的局限,它允许Struts应用灵活的配置验证规则,无需编程。
Validator框架主要依赖两个JAR文件:jakarta-oro.jar和commons-validator,.jar
Validator框架采用两个基于XML的配置文件来配置验证规则。这两个文件为validator-rules.xml和validation.xml。
1. struts调用validator框架的过程:
struts-config.xml 文件中配置struts的validator插件
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml, /WEB-INF/validation.xml"/>
</plug-in>
容器启动时,ActionServlet调用插件ValidatorPlugIn的init方法。
init方法首先调用initResources方法,此方法通过读取参数pathnames取得值value并分析这两个xml文件,返回validatorResources对象。然后将这个对象保存进application作用域。
public void init(ActionServlet servlet, ModuleConfig config)
throws ServletException {
......
try {
this.initResources();
servlet.getServletContext().setAttribute(VALIDATOR_KEY
+ config.getPrefix(), resources);
.....
} catch (Exception e) {
......
}
当服务器接受请求,它会调用ValidatorForm类的validate方法进行表单验证。
ValidatorForm的validate方法中调用Resources.InitValidator方法初始化Validator对象,并调用setParamter方法为校验方法传递参数,最后调用validator.validate()方法执行校验。
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
......
String validationKey = getValidationKey(mapping, request);
//返回Validator对象
Validator validator =
Resources.initValidator(validationKey, this, application, request, errors, page);
try {
validatorResults = validator.validate();
} catch (ValidatorException e) {
......
}
return errors;
}
public static Validator initValidator(......){
......
ValidatorResources resources =
Resources.getValidatorResources(application, request);
//通过rources和formbean的名字得到Validator对象。
Validator validator = new Validator(resources, key);
validator.setParameter(SERVLET_CONTEXT_PARAM, application);
validator.setParameter(HTTP_SERVLET_REQUEST_PARAM, request);
validator.setParameter(Validator.LOCALE_PARAM, locale);
validator.setParameter(ACTION_MESSAGES_PARAM, errors);
validator.setParameter(Validator.BEAN_PARAM, bean);
......
}
public String getValidationKey(ActionMapping mapping,
HttpServletRequest request) {
return mapping.getAttribute();
}
这里:getValidationKey返回struts-config.xml中action元素的attribute属性的值,它对应Form的name属性的值,表示要对哪个formbean进行校验。
<form name="regUserForm">
<field property="name" depends="required">
。。。
</field>
validator的validate()方法调用Form,Field对象(根据配置文件实例化对象)的validate方法分别进行校验,返回一个ValidatorResults对象。ValidatorResults对象包含所有校验的结果。
2.如何扩展自己的校验器。
package com.wll.util;
import java.io.Serializable;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.Validator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.util.ValidatorUtils;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.validator.Resources;
public class MyFieldChecks implements Serializable {
public static boolean validateIdCard(Object bean,
ValidatorAction va, Field field,
ActionMessages errors,
Validator validator,
HttpServletRequest request) {
String value = null;
value = ValidatorUtils.getValueAsString(bean, field.getProperty());
if (value.length()!=15 || !isDigits(value)){
errors.add(field.getKey(), Resources.getActionMessage(validator, request, va, field));
return false;
}
return true;
}
private static boolean isDigits(String value) {
// TODO Auto-generated method stub
int len = value.length();
for(int i=0;i<len;i++)
{
if(!Character.isDigit(value.charAt(i)))
return false;
}
return true;
}
}
配置如下:
validation.xml
<form name="creditCard">
<field property="card" depends="cardRequired">
<arg key="prompt.card"/>
</field>
</form>
validator-rules.xml
<validator name="cardRequired"
classname=" com.wll.util.MyFieldChecks"
method=" validateIdCard "
methodParams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest"
msg="errors.card"/>
资源文件中
errors.card={0} is not valid.
prompt.card=creditcard