Struts2 输入的验证
1 验证分为两种:
a) 声明式验证(*)
>> 对哪个 Action 或 Model 的那个字段进行验证
>> 使用什么验证规则
>> 如果验证失败,转向哪一个页面, 显示是什么错误消息
b) 编程式验证
1 声明式验证的 helloworld
1) 先明确对哪一个 Action 的哪一个字段进行验证;
2) 编写配置文件:
> 把 struts-2.3.15.3\apps\struts2-blank\WEB-INF\classes\example 下的 Login-validation.xml 文件复制到当前 Action 所在的包下;
> 把该配置文件(Login-validation.xml)改为当前 Action 的名字(Actionname-validation.xml);
> 编写验证规则:参见 struts-2.3.15.3/docs/WW/docs/validation.html 文档即可;
> 在配置文件中可以定义错误消息:
<field name="age">
<field-validator type="int">
<param name="min">20</param>
<param name="max">50</param>
<message>^^Age needs to be between ${min} and ${max}</message>
</field-validator>
</field>
> 该错误消息可以国际化吗?答案是肯定的。
<message key="error.int"></message>
再在国际化资源文件中加入一个键值对:error.int=Age needs to be between ${min} and ${max}
3) 若验证失败,则转向 input 的那个 result。所以需要配置 name=input 的 result
<result name="input">/validation.jsp</result>
4) 如何显示错误消息呢 ?
> 若使用的是非 simple主题,则自动显示错误消息。
> 若使用的是 simple 主题,则需要 s:fielderror 标签或直接使用 EL 表达式(使用 OGNL):
${fieldErrors.age[0] } 或 <s:fielderror fieldName="age"></s:fielderror>
问题一: 若一个 Action 类可以应答多个 action 请求,多个 action 请求使用不同的验证规则, 怎么办 ?
> 为每一个不同的 action 请求定义其对应的验证文件:ActionClassName-AliasName-validation.xml ,其中AliasName为struts.xml中<action></action>标签name的值。
> 不带别名的配置文件:ActionClassName-validation.xml 中的验证规则依然会发生作用。可以把各个 action 公有的验证规则配置在其中。但需要注意的是,只适用于某一个 action 的请求的验证规则就不要这里再配置了。
5) 声明式验证框架的原理
> Struts2 默认的拦截器栈中提供了一个 validation 拦截器
> 每个具体的验证规则都会对应具体的一个验证器。有一个配置文件把验证规则名称和验证器关联起来了。而实际上验证的是那个验证器。该文件位于 com.opensymphony.xwork2.validator.validators 下的 default.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator Definition 1.0//EN"
"http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd">
<!-- START SNIPPET: validators-default -->
<validators>
<validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
<validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
<validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
<validator name="long" class="com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator"/>
<validator name="short" class="com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator"/>
<validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
<validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
<validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
<validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
<validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
<validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
<validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
<validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
<validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
<validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>
<validator name="conditionalvisitor" class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/>
</validators>
<!-- END SNIPPET: validators-default -->
6) 短路验证:若对一个字段使用多个验证器,默认情况下会执行所有的验证。若希望前面的验证器验证没有通过,后面的就不再验证,可以使用短路验证。
<!-- 设置短路验证:若当前验证没有通过,则不再进行下面的验证 -->
<field-validator type="conversion" short-circuit="true">
<message>^Conversion Error Occurred</message>
</field-validator>
<field-validator type="int">
<param name="min">20</param>
<param name="max">60</param>
<message key="error.int"></message>
</field-validator>
7) 若类型转换失败,默认情况下还会执行后面的拦截器,还会进行 验证。可以通过修改 ConversionErrorInterceptor 源代码的方式使当类型转换失败时,不再执行后续的验证拦截器。而直接返回 input 的 result
修改方法为:
a) 建立与原ConversionErrorInterceptor类相同的包并把源代码复制过来;
b) 在新的ConversionErrorInterceptor类代码“return invocation.invoke();”之前添加下面处理:
Object action = invocation.getAction();
if (action instanceof ValidationAware) {
ValidationAware va = (ValidationAware) action;
if(va.hasFieldErrors() || va.hasActionErrors()){
return "input";
}
}
8) 关于非字段验证:不是针对于某一个字段的验证。
a) 配置验证
<validator type="expression">
<param name="expression"><![CDATA[password==repassword]]></param>
<message>Password is not equals to repassword</message>
</validator>
b) 显示非字段验证的错误消息,使用 s:actionerror 标签:<s:actionerror/>
问题二:如何复用验证失败错误提示信息? 即不同的字段验证使用统一验证器,使用同一错误提示信息时,可以定制话提示用户。
1) 配置字段验证
2) 配置国际化文件
error.int=${getText(fieldName)} needs to be between ${min} and ${max}
age=\u5E74\u9F84
count=\u6570\u91CF
自定义验证器
1. 定义一个验证器的类
> 自定义的验证器都需要实现 Validator,可以选择继承 ValidatorSupport 或 FieldValidatorSupport 类。若希望实现一个一般的验证器,则可以继承 ValidatorSupport。若希望实现一个字段验证器,则可以继承 FieldValidatorSupport。
> 具体实现可以参考目前已经有的验证器。
> 若验证程序需要接受一个输入参数,需要在验证器类中为这个参数增加一个相应的属性并添加对应的set方法。
2.在配置文件中配置验证器
> 默认情况下下,Struts2 会在 类路径的根目录下加载 validators.xml 文件中的验证器。该文件的定义方式同默认的验证器的那个配置文件:位于 com.opensymphony.xwork2.validator.validators 下的 default.xml。
> 若类路径下没有指定的验证器,则加载 com.opensymphony.xwork2.validator.validators 下的 default.xml 文件中的验证器。
3. 使用:使用方法和系统内置的验证器相同。
4. 示例:自定义一个 18 位身份证验证器
本文深入探讨了Struts2输入验证的两种主要方法:声明式验证和编程式验证。详细介绍了验证配置、错误消息国际化、短路验证、非字段验证及如何复用验证失败错误提示信息等内容。
494

被折叠的 条评论
为什么被折叠?



