校验是所有web框架中都需要的一个功能。下面让我们来对校验问题进行一个分析:
校验问题的分类:
- 转型校验:由于页面提交过的来所有数据都是text,而web框架中处理的都是对象,需要转型。
而转型过程中不可避免的需要校验。
- 用户自定义的数据校验:转型后的数据用户往往还有许多自定义的校验要求,比如年龄必须是自然数等,那就要允许用户对表单的每个字段可以 采用描述性的配置说明需要的检验。但此校验一般不涉及model中的服务。
- 涉及model的校验:有些校验必须访问后台服务才能进行,如登录时用户名密码的检验需访问model中的服务去进行校验。
对于以上三种校验问题的解决,以及校验的顺序构成了strurts2的校验框架的基本思路.其中parametersInterceptor,ConversionErrorInterceptor解决转型校验,ValidationInterceptor解决用户自定义数据校验和涉及model校验。
1.ParametersInterceptor
将parameters中提交的表单值转型并设置到ValueStack中去,在转型过程中出现type conversion error时,将context中 key=com.opensymphony.xwork2.ActionContext.conversionErrors对应的map中将对应的type convertion 失败的属性名称和及其值对保存起来。
类:com.opensymphony.xwork2.interceptor. ParametersInterceptor
方法:protected void setParameters(Object action, ValueStack stack, final Map<String, Object> parameters)
代码:
stack.getContext().put(ActionContext.CONVERSION_ERRORS, newStack.getContext().get(ActionContext.CONVERSION_ERRORS));
2.ConversionErrorInterceptor
根据type conversion失败的属性名称和其值结合出错信息模板生成出错信息加入ValidationAware里的对应字段的FieldError
类:com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor
方法: public String intercept(ActionInvocation invocation)
a) String message = XWorkConverter.getConversionErrorMessage(propertyName, stack);
类:com.opensymphony.xwork2.conversion.impl.XWorkConverter
方法:public static String getConversionErrorMessage(String propertyName, ValueStack stack)
i. 先去找prop key=xwork.default.invalid.fieldvalue的值,默认去org/apache/struts2/struts-messages和com/opensymphony/xwork2/xwork-messages中找。
ii. 再去用prop key=invalid.fieldvalue.+fieldName找对应的信息
iii. 如果ii存在,则以ii为基础生成出错的信息,否则取i。
b) ValidationAware va = (ValidationAware) action;
va.addFieldError(propertyName, message);
将生成错误信息放入FieldError
3.ValidationInterceptor
类:com.opensymphony.xwork2.interceptor.ValidationInterceptor
方法: protected void doBeforeInvocation(ActionInvocation invocation)
a) actionValidatorManager.validate(action, context);
调用所有validator校验数据,在ValidationAware中存储FieldError,ActionError。
b) PrefixMethodInvocationUtil.invokePrefixMethod(
invocation,
new String[] { VALIDATE_PREFIX, ALT_VALIDATE_PREFIX });
检查是否存在validate, validateDo+method的方法,如果按顺序有则返回调用之
c) 最后调用validateable.validate();方法
4.展现出错信息:
使用<s:fielderror >标签,其中属性名称在<s:param>price</s:param>里可指定