(1) 添加校验项
修改文件
src/main/resources/com/mycompany/app/model/Person-validation.xml
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
重新编译,重新访问添加人员的页面,姓、名设置为空直接保存,报错
校验起了作用
(2) struts.xml文件的配置说明
......
。。。。。。
(3) 校验流程分析
struts.xml中定义默认包时
而在struts-default.xml中,配置了如下的拦截器
input,back,cancel
当执行添加操作时会被validation拦截器拦截
AnnotationValidationInterceptor中的doIntercept方法
protected String doIntercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();
if (action != null) {
Method method = getActionMethod(action.getClass(), invocation.getProxy().getMethod());
SkipValidation skip = (SkipValidation) method.getAnnotation(SkipValidation.class);
if (skip != null) {
return invocation.invoke();
}
}
return super.doIntercept(invocation);
}
再看父类的doIntercept方法
protected String doIntercept(ActionInvocation invocation) throws Exception {
doBeforeInvocation(invocation);
return invocation.invoke();
}
再看触发前要执行的方法doBeforeInvocation(invocation)
protected void doBeforeInvocation(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();
String context = invocation.getProxy().getActionName();
String method = invocation.getProxy().getMethod();
if (log.isDebugEnabled()) {
log.debug("Validating "
+ invocation.getProxy().getNamespace() + "/" + invocation.getProxy().getActionName() + " with method "+ method +".");
}
if (validateAnnotatedMethodOnly) {
ActionValidatorManagerFactory.getInstance().validate(action, context, method);
} else {
ActionValidatorManagerFactory.getInstance().validate(action, context);
}
}
再看ActionValidatorManagerFactory.getInstance()
public class ActionValidatorManagerFactory {
private static final Log LOG = LogFactory.getLog(ActionValidatorManagerFactory.class);
private static ActionValidatorManager instance = new DefaultActionValidatorManager();
static {
try {
Class c = ClassLoaderUtil.loadClass("com.opensymphony.xwork2.validator.AnnotationActionValidatorManager", ActionValidatorManagerFactory.class);
LOG.info("Detected AnnotationActionValidatorManager, initializing it...");
instance = (ActionValidatorManager) c.newInstance();
} catch (ClassNotFoundException e) {
// this is fine, just fall back to the default object type determiner
} catch (Exception e) {
throw new XWorkException(e);
}
}
public static void setInstance(ActionValidatorManager instance) {
ActionValidatorManagerFactory.instance = instance;
}
public static ActionValidatorManager getInstance() {
return instance;
}
}
再看com.opensymphony.xwork2.validator.AnnotationActionValidatorManager中的validate(Object object, String context, ValidatorContext validatorContext, String method)方法
public void validate(Object object, String context, ValidatorContext validatorContext, String method) throws ValidationException {
List validators = getValidators(object.getClass(), context, method);
Set shortcircuitedFields = null;
for (final Validator validator: validators) {
try {
validator.setValidatorContext(validatorContext);
if (LOG.isDebugEnabled()) {
LOG.debug("Running validator: " + validator + " for object " + object + " and method " + method);
}
FieldValidator fValidator = null;
String fullFieldName = null;
if (validator instanceof FieldValidator) {
fValidator = (FieldValidator) validator;
fullFieldName = fValidator.getValidatorContext().getFullFieldName(fValidator.getFieldName());
if ((shortcircuitedFields != null) && shortcircuitedFields.contains(fullFieldName)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Short-circuited, skipping");
}
continue;
}
}
if (validator instanceof ShortCircuitableValidator && ((ShortCircuitableValidator) validator).isShortCircuit())
{
// get number of existing errors
List errs = null;
if (fValidator != null) {
if (validatorContext.hasFieldErrors()) {
Collection fieldErrors = (Collection) validatorContext.getFieldErrors().get(fullFieldName);
if (fieldErrors != null) {
errs = new ArrayList(fieldErrors);
}
}
} else if (validatorContext.hasActionErrors()) {
Collection actionErrors = validatorContext.getActionErrors();
if (actionErrors != null) {
errs = new ArrayList(actionErrors);
}
}
validator.validate(object);
if (fValidator != null) {
if (validatorContext.hasFieldErrors()) {
Collection errCol = (Collection) validatorContext.getFieldErrors().get(fullFieldName);
if ((errCol != null) && !errCol.equals(errs)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Short-circuiting on field validation");
}
if (shortcircuitedFields == null) {
shortcircuitedFields = new TreeSet();
}
shortcircuitedFields.add(fullFieldName);
}
}
} else if (validatorContext.hasActionErrors()) {
Collection errCol = validatorContext.getActionErrors();
if ((errCol != null) && !errCol.equals(errs)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Short-circuiting");
}
break;
}
}
continue;
}
validator.validate(object);
} finally {
validator.setValidatorContext( null );
}
}
}
最后看一下校验必填项的实现
public class RequiredFieldValidator extends FieldValidatorSupport {
public void validate(Object object) throws ValidationException {
String fieldName = getFieldName();
Object value = this.getFieldValue(fieldName, object);
if (value == null) {
addFieldError(fieldName, object);
}
}
}
到这里,校验表单,出错后将执行addFieldError方法