1.Using Annotations(利用java5的标记实现验证)
[list]
[*]该方式的验证必须在class级别上声明@Validation()属性代码如下
[*]在字段的setter方法上定义验证的规则
field validation的声明方式
plain validation的声明方式
[*]采用该方式验证可以减少配置文件的数量但是关于验证错误信息中对localization的支持有待调查。
[/list]
2.Examples(使用用例)
[list]
[*]Basic Validation
主要一点就是声明validation.xml 文件放在action类的包下,命名规则为 <ActionClassName>-validation.xml or <ActionClassName>-<ActionAliasName>-validation.xml
[*]Client Validation
服务器端的配置代码和Basic Validation的代码一直不同的地方在于在jsp页面上声明s:form标记的时候必须指定 validate="true"属性,并且不支持把namespace写在action上而要直接写在页面的namespace属性上。实际应用如下
not work
[*]AJAX Validation
2.0.x版本的ajax验证是和DWR结合的,文档中介绍的是和Dojo结合的版本。
服务器端配置除了Basic Validation,需要在struts.xml文件中加入如下拦截器
在页面上的form标签中加入theme="xhtml"属性并且没有validate="true"属性
在head中加入<sx:head />
在s:submit按钮(可以使其他控件例如bind)中加入validate="true"属性
如果需要进一步使用ajax提交,需要在s:submit,ajaxAfterValidation="true"
Setting validate to true in the form tag还是可以打开JavaScript验证,不过该验证会在ajax验证前执行。
工作原理
jsonValidation必须在正常的validation拦截器之后执行。
该拦截器先检查struts.enableJSONValidation属性为true则执行ajax验证。
检查 struts.validateOnly为true并且存在validation错误的时候,把错误信息序列化为JSON
在客户端使用utils.js中StrutsUtils.
Include prototype.js,utils.js and validation.js(the one for the theme being used), if you are not using the Dojo plugin.
详细的验证流程参考文档中的处理流程图.
[*]Field Validators
这种校验器需要嵌套在<field name="stringLengthValidatorField">标签中使用。
并且可以在field标签中定义多个<field-validator type="stringlength">validator。
该校验器有两种形式还可以使用plain validator中加入fieldname属性来实现这种校验器。
[*]Non Field Validators
该校验器的工作方式如下
[*]Visitor Field Validator
这种vistor用于定义使用某个对象自己的校验器进行数据的校验。
该校验器可以校验对象,数组,结合等等的元素。
context属性用于指定用于验证对象所对应的xml文件名字规则。如果需要验证的对象的名字为User那么寻找的校验文件的路径为User-Context-validation.xml
appendPrefix指定是否需要在属性前面添加前缀,前缀为fieldname如果filename为user那么指定appendPrefix后验证的实际字段名就为user.name
[/list]
3.Bundled Validators(系统预定义的校验器)
[list]
[*]conversion validator--ConversionErrorFieldValidator
用于检查所校验的字段是否存在类型转化错误。
可以定义repopulateField用于保留转化错误前的用户输入值。
实现的原理主要是把捕获页面的conversion错误并且获取该字段的错误信息,添加到对应的context中。
repopulateField的实现是定义从context的errors中获取到该字段的用户输入值,并且利用preresultlistener在用户执行完action后,result执行前,改变statck中该value的值为用户错误输入的值。
[*]date validator--DateRangeFieldValidator
用于判断date类型的数据的大小
通过继承AbstractRangeValidator并且date类型的数据实现了Comparable接口来实现多种数据类型的比较。
详细比较代码如下
[*]double validator--DoubleRangeFieldValidator
实现了double类型数值的比较
Inclusive为min<a<max
Exclusive为<=min >=max
[*]email validator--EmailValidator
校验email格式是否正确
该校验器其实是继承正则表达式实现的。表达式如下
"\\b(^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@([A-Za-z0-9-])+(\\.[A-Za-z0-9-]+)*((\\.[A-Za-z0-9]{2,})|(\\.[A-Za-z0-9]{2,}\\.[A-Za-z0-9]{2,}))$)\\b"
[*]expression validator--ExpressionValidator
利用ongl表达式校验field的值。
表达式必须能返回Boolean的值。
[*]fieldexpression validator--FieldExpressionValidator
校验ognl表达式的值,必须指定filedname,并且错误信息是field级别的。
[*]int validator--IntRangeFieldValidator
实现和date一致.
[*]regex validator--RegexFieldValidator
利用正则表达式校验某个字段的值。
[*]required validator
验证某个字段非空
[*]requiredstring validator
判断值是否是字符串,而且判断字符串长度是否大于0
[*]stringlength validato
判断字符串的长度范围.
[*]url validator--URLValidator
判断字符串格式是否符合url的格式
实际调用TextUtils.verifyUrl方法实现.
[*]visitor validator--VisitorFieldValidator
实现上一章节已经讲到这里不在鏊述。
[/list]
4.Registering Validators
[list]
[*]通过ValidatorFactory.parseValidators()方法解析加载所有配置文件中有定义的validator,系统只记住validator的名字和对应的实现类的包全路径。
[*]加载过程会寻找的文件如下classpath中的validators.xml,com/opensymphony/xwork2/validator/validators/default.xml,com/opensymphony/xwork2/validator/validators中-validators.xml结尾的所有文件.
[/list]
5.Turning on Validation(添加验证拦截器)
加入如下拦截器到栈中
6.Defining Validation Rules
[list]
[*]校验文件的路径的查找规则
(1)Per Action class: in a file named ActionName-validation.xml
(2)Per Action alias: in a file named ActionName-alias-validation.xml
(3)以上都找不到则会递归的往对象的继承类或者接口类上一直找到Object.class
代码如下
[/list]
7.Localizing and Parameterizing Messages(messae信息的本地化和参数化)
validator的message元素可以定义key属性,用户从resource bundle文件中获取消息体,
并且用ognl表达式获取相对应的值.
也可以直接在ognl表达式中用getText方法直接查找resource bundle中的值.例子如下
8.Validator Flavour
当校验的信息是针对字段的时候采用field-validator会更加好理解。
9.Short-Circuiting Validator(短路)
Plain validator 优先于 field-validator.
校验过程中将先校验Plain validator后校验field-validator.
只要有Plain validator短路,其余的所有validator都不会被校验。
field-validator如果定义了短路属性,只会短相同fieldname的其他校验器,而不会影响到其他field的校验器,包括Plain validator
:arrow:
[list]
[*]该方式的验证必须在class级别上声明@Validation()属性代码如下
@Validation()
public class SimpleAnnotationAction extends ActionSupport {
}
[*]在字段的setter方法上定义验证的规则
field validation的声明方式
@RequiredFieldValidator(type = ValidatorType.FIELD, message = "You must enter a value for bar.")
@IntRangeFieldValidator(type = ValidatorType.FIELD, min = "6", max = "10", message = "bar must be between ${min} and ${max}, current value is ${bar}.")
public void setBar(int bar) {
this.bar = bar;
}
plain validation的声明方式
@Validations(
requiredFields =
{@RequiredFieldValidator(type = ValidatorType.SIMPLE, fieldName = "customfield", message = "You must enter a value for field.")},
requiredStrings =
{@RequiredStringValidator(type = ValidatorType.SIMPLE, fieldName = "stringisrequired", message = "You must enter a value for string.")},
emails =
{ @EmailValidator(type = ValidatorType.SIMPLE, fieldName = "emailaddress", message = "You must enter a value for email.")},
urls =
{ @UrlValidator(type = ValidatorType.SIMPLE, fieldName = "hreflocation", message = "You must enter a value for email.")},
stringLengthFields =
{@StringLengthFieldValidator(type = ValidatorType.SIMPLE, trim = true, minLength="10" , maxLength = "12", fieldName = "needstringlength", message = "You must enter a stringlength.")},
intRangeFields =
{ @IntRangeFieldValidator(type = ValidatorType.SIMPLE, fieldName = "intfield", min = "6", max = "10", message = "bar must be between ${min} and ${max}, current value is ${bar}.")},
dateRangeFields =
{@DateRangeFieldValidator(type = ValidatorType.SIMPLE, fieldName = "datefield", min = "-1", max = "99", message = "bar must be between ${min} and ${max}, current value is ${bar}.")},
expressions = {
@ExpressionValidator(expression = "foo > 1", message = "Foo must be greater than Bar 1. Foo = ${foo}, Bar = ${bar}."),
@ExpressionValidator(expression = "foo > 2", message = "Foo must be greater than Bar 2. Foo = ${foo}, Bar = ${bar}."),
@ExpressionValidator(expression = "foo > 3", message = "Foo must be greater than Bar 3. Foo = ${foo}, Bar = ${bar}."),
@ExpressionValidator(expression = "foo > 4", message = "Foo must be greater than Bar 4. Foo = ${foo}, Bar = ${bar}."),
@ExpressionValidator(expression = "foo > 5", message = "Foo must be greater than Bar 5. Foo = ${foo}, Bar = ${bar}.")
}
[*]采用该方式验证可以减少配置文件的数量但是关于验证错误信息中对localization的支持有待调查。
[/list]
2.Examples(使用用例)
[list]
[*]Basic Validation
主要一点就是声明validation.xml 文件放在action类的包下,命名规则为 <ActionClassName>-validation.xml or <ActionClassName>-<ActionAliasName>-validation.xml
[*]Client Validation
服务器端的配置代码和Basic Validation的代码一直不同的地方在于在jsp页面上声明s:form标记的时候必须指定 validate="true"属性,并且不支持把namespace写在action上而要直接写在页面的namespace属性上。实际应用如下
<s:form method="post" validate="true" action="quizClient" namespace="/validation">
not work
<s:form method="post" validate="true" action="/validation/quizClient.action">
[*]AJAX Validation
2.0.x版本的ajax验证是和DWR结合的,文档中介绍的是和Dojo结合的版本。
服务器端配置除了Basic Validation,需要在struts.xml文件中加入如下拦截器
<interceptor-ref name="jsonValidationWorkflowStack"/>
在页面上的form标签中加入theme="xhtml"属性并且没有validate="true"属性
在head中加入<sx:head />
在s:submit按钮(可以使其他控件例如bind)中加入validate="true"属性
如果需要进一步使用ajax提交,需要在s:submit,ajaxAfterValidation="true"
Setting validate to true in the form tag还是可以打开JavaScript验证,不过该验证会在ajax验证前执行。
工作原理
jsonValidation必须在正常的validation拦截器之后执行。
该拦截器先检查struts.enableJSONValidation属性为true则执行ajax验证。
检查 struts.validateOnly为true并且存在validation错误的时候,把错误信息序列化为JSON
在客户端使用utils.js中StrutsUtils.
Include prototype.js,utils.js and validation.js(the one for the theme being used), if you are not using the Dojo plugin.
详细的验证流程参考文档中的处理流程图.
[*]Field Validators
这种校验器需要嵌套在<field name="stringLengthValidatorField">标签中使用。
并且可以在field标签中定义多个<field-validator type="stringlength">validator。
该校验器有两种形式还可以使用plain validator中加入fieldname属性来实现这种校验器。
[*]Non Field Validators
该校验器的工作方式如下
<validator type="expression">
<param name="expression"><![CDATA[ ( (someText == someTextRetype) && (someTextRetype == someTextRetypeAgain) ) ]]></param>
<message><![CDATA[ all three text must be exactly the same ]]></message>
</validator>
[*]Visitor Field Validator
这种vistor用于定义使用某个对象自己的校验器进行数据的校验。
该校验器可以校验对象,数组,结合等等的元素。
context属性用于指定用于验证对象所对应的xml文件名字规则。如果需要验证的对象的名字为User那么寻找的校验文件的路径为User-Context-validation.xml
appendPrefix指定是否需要在属性前面添加前缀,前缀为fieldname如果filename为user那么指定appendPrefix后验证的实际字段名就为user.name
[/list]
3.Bundled Validators(系统预定义的校验器)
[list]
[*]conversion validator--ConversionErrorFieldValidator
用于检查所校验的字段是否存在类型转化错误。
可以定义repopulateField用于保留转化错误前的用户输入值。
实现的原理主要是把捕获页面的conversion错误并且获取该字段的错误信息,添加到对应的context中。
repopulateField的实现是定义从context的errors中获取到该字段的用户输入值,并且利用preresultlistener在用户执行完action后,result执行前,改变statck中该value的值为用户错误输入的值。
[*]date validator--DateRangeFieldValidator
用于判断date类型的数据的大小
通过继承AbstractRangeValidator并且date类型的数据实现了Comparable接口来实现多种数据类型的比较。
详细比较代码如下
if ((getMinComparatorValue() != null) && (value.compareTo(getMinComparatorValue()) < 0)) {
addFieldError(getFieldName(), object);
}
// only check for a maximum value if the max parameter is set
if ((getMaxComparatorValue() != null) && (value.compareTo(getMaxComparatorValue()) > 0)) {
addFieldError(getFieldName(), object);
}
[*]double validator--DoubleRangeFieldValidator
实现了double类型数值的比较
Inclusive为min<a<max
Exclusive为<=min >=max
[*]email validator--EmailValidator
校验email格式是否正确
该校验器其实是继承正则表达式实现的。表达式如下
"\\b(^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@([A-Za-z0-9-])+(\\.[A-Za-z0-9-]+)*((\\.[A-Za-z0-9]{2,})|(\\.[A-Za-z0-9]{2,}\\.[A-Za-z0-9]{2,}))$)\\b"
[*]expression validator--ExpressionValidator
利用ongl表达式校验field的值。
表达式必须能返回Boolean的值。
[*]fieldexpression validator--FieldExpressionValidator
校验ognl表达式的值,必须指定filedname,并且错误信息是field级别的。
[*]int validator--IntRangeFieldValidator
实现和date一致.
[*]regex validator--RegexFieldValidator
利用正则表达式校验某个字段的值。
[*]required validator
验证某个字段非空
[*]requiredstring validator
判断值是否是字符串,而且判断字符串长度是否大于0
[*]stringlength validato
判断字符串的长度范围.
[*]url validator--URLValidator
判断字符串格式是否符合url的格式
实际调用TextUtils.verifyUrl方法实现.
[*]visitor validator--VisitorFieldValidator
实现上一章节已经讲到这里不在鏊述。
[/list]
4.Registering Validators
[list]
[*]通过ValidatorFactory.parseValidators()方法解析加载所有配置文件中有定义的validator,系统只记住validator的名字和对应的实现类的包全路径。
[*]加载过程会寻找的文件如下classpath中的validators.xml,com/opensymphony/xwork2/validator/validators/default.xml,com/opensymphony/xwork2/validator/validators中-validators.xml结尾的所有文件.
[/list]
5.Turning on Validation(添加验证拦截器)
加入如下拦截器到栈中
<interceptor name="validator" class="com.opensymphony.xwork2.validator.ValidationInterceptor"/>
6.Defining Validation Rules
[list]
[*]校验文件的路径的查找规则
(1)Per Action class: in a file named ActionName-validation.xml
(2)Per Action alias: in a file named ActionName-alias-validation.xml
(3)以上都找不到则会递归的往对象的继承类或者接口类上一直找到Object.class
代码如下
if (clazz.isInterface()) {
for (Class anInterface : clazz.getInterfaces()) {
validatorConfigs.addAll(buildValidatorConfigs(anInterface, context, checkFile, checked));
}
} else {
if (!clazz.equals(Object.class)) {
validatorConfigs.addAll(buildValidatorConfigs(clazz.getSuperclass(), context, checkFile, checked));
}
}
[/list]
7.Localizing and Parameterizing Messages(messae信息的本地化和参数化)
validator的message元素可以定义key属性,用户从resource bundle文件中获取消息体,
并且用ognl表达式获取相对应的值.
也可以直接在ognl表达式中用getText方法直接查找resource bundle中的值.例子如下
<message>${getText("validation.failednotice")}! ${getText("reason")}: ${getText("validation.inputrequired")}</message>
8.Validator Flavour
当校验的信息是针对字段的时候采用field-validator会更加好理解。
9.Short-Circuiting Validator(短路)
Plain validator 优先于 field-validator.
校验过程中将先校验Plain validator后校验field-validator.
只要有Plain validator短路,其余的所有validator都不会被校验。
field-validator如果定义了短路属性,只会短相同fieldname的其他校验器,而不会影响到其他field的校验器,包括Plain validator
:arrow: