概述
一个健壮的 web 应用程序必须确保用户输入是合法、有效的。
Struts2 的输入验证有两种方式:
1. 基于 XWork Validation Framework 的声明式验证:Struts2 提供了一些基于 XWork Validation Framework 的内建验证程序。使用这些验证程序不需要编程,只要在一个 XML 文件里对验证程序应该如何工作作出声明就可以了。 需要声明的内容包括:
a) 哪些字段需要进行验证
b) 使用什么验证规则
c) 在验证失败时应该把什么样的出错消息发送到浏览器端
2. 编程验证:通过编写代码来验证用户输入
声明式验证
声明式验证程序可以分为两类:
字段验证:判断某个字段属性的输入是否有效
非字段验证:不只针对某个字段,而是针对多个字段的输入值之间的逻辑关系进行校验。例如:用户注册时对再次输入密码的判断。
使用一个声明式验证程序需要 3 个步骤:
1. 确定哪些 Action 字段需要验证
2. 编写一个验证程序配置文件,它的文件名必须是以下两种格式之一:
若一个 Action 类的多个 action 使用同样的验证规则:ActionClassName-validation.xml
若一个 Action 类的多个 action 使用不同的验证规则:ActionClass-alias-validation.xml,例如 UserAction-create-validation.xml
3. 确定验证失败时的响应页面:在 struts.xml 文件中定义一个 <result name=“input”> 的元素。
Struts2 内建的验证规则
conversion validator:转换验证器
date validator:日期验证器
double validator:浮点验证器
email validator:email 验证器
expression validator:表达式验证器
fieldexpression validator:字段表达式验证器
int validator:整型验证器
regex validator:正则表达式验证器
required validator:非空验证器
requiredstring validator:非空字符串验证器
stringlength validator:字符串长度验证器
url validator:url 格式验证器
visitor validator:复合属性验证器
Struts2 内建的验证程序
required: 确保某给定字段的值不是空值 null “”
requiredstring: 确保某给定字段的值既不是空值 null, 也不是空白.
trim 参数. 默认为 true, 表示 struts 在验证该字段值之前先剔除前后空格.
stringlength: 验证一个非空的字段值是不是有足够的长度.
minLength: 相关字段的最小长度. 若没有给出这个参数, 该字段将没有最小长度限制
maxLength:相关字段的最大长度. 若没有给出这个参数, 该字段将没有最大长度限制
trim: 在验证之前是否去除前后空格
date: 确保某给定日期字段的值落在一个给定的范围内
max:相关字段的最大值. 若没给出这个参数, 该字段将没有最大值限制
min:相关字段的最小值. 若没给出这个参数, 该字段将没有最小值限制
email: 检查给定 String 值是否是一个合法的 email
url: 检查给定 String 值是否是一个合法的 url
regex: 检查某给定字段的值是否与一个给定的正则表达式模式相匹配.
expresssion*: 用来匹配的正则表达式
caseSensitive: 是否区分字母的大小写. 默认为 true
trim: 是否去除前后空格. 默认为 true
int: 检查给定整数字段值是否在某一个范围内
min: 相关字段的最小值. 若没给出这个参数, 该字段将没有最小值限制
max: 相关字段的最大值. 若没给出这个参数, 该字段将没有最大值限制
conversion: 检查对给定 Action 属性进行的类型转换是否会导致一个转换错误. 该验证程序还可以在默认的类型转换消息的基础上添加一条自定义的消息
expression 和 fieldexpression: 用来验证给定字段是否满足一个 OGNL 表达式.
前者是一个非字段验证程序, 后者是一个字段验证程序.
前者在验证失败时将生成一个 action 错误, 而后者在验证失败时会生成一个字段错误
expression*: 用来进行验证的 OGNL 表达式
<validator type="expression"> <param name="expression"><![CDATA[(password==repassword)]]></param> <message>两次输入密码不一致</message> </validator>
每个验证规则都对应一个具体的验证器
在xwork-core-2.3.15.3.jar包的com.opensymphony.xwork.validator.validators目录下文件defualt.xml中配置了系统默认的拦截器:
<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>
验证程序的配置
Struts2 的 Validation 拦截器负责加载和执行已注册的验证程序,它是 defaultStack 拦截器的一员
短路验证器
<validator …/> 元素和 <field-validator …/> 元素可以指定一个可选的 short-circuit 属性,该属性指定该验证器是否是短验证器,默认值为 false。
对同一个字段内的多个验证器,如果一个短路验证器验证失败,其他验证器不会继续校验
非字段验证示例
<validator type="expression"> <param name="expression"><![CDATA[(password==repassword)]]></param> <message>两次输入密码不一致</message> </validator>
字段验证 vs 非字段验证
字段验证字段优先,可以为一个字段配置多个验证规则
非字段验证验证规则优先
大部分验证规则支持两种验证器,但个别的验证规则只能使用非字段验证,例如表达式验证。
错误消息的重用性
多个字段使用同样的验证规则,可否使用同一条验证消息 ?
自定义验证器
自定义验证器必须实现 Validator 接口.
ValidatorSupport 和 FieldValidatorSupport 实现了 Validator 接口
若需要普通的验证程序, 可以继承 ValidatorSupport 类
若需要字段验证程序, 可以继承 FieldValidatorSupport 类
若验证程序需要接受一个输入参数, 需要为这个参数增加一个相应的属性
注册验证程序: 自定义验证器需要在类路径里的某个 validators.xml 文件里注册: 验证框架首先在根目录下找validators.xml文件,没找到validators.xml文件, 验证框架将调用默认的验证设置,即default.xml里面的配置信息.
自定义一个 18 位身份证验证器
编写验证器类
在 validators.xml 文件中进行注册
在验证配置文件中使用
编程验证
Struts2 提供了一个 Validateable 接口, 可以使 Action 类实现这个接口以提供编程验证功能.
ActionSupport 类已经实现了 Validateable 接口
编程验证方法
1. 使Action继承ActionSupport
2. 重写validate方法,在此方法中完成验证
@Override
public void validate() {
if(username == null || username.trim().equals(""))
{
addFieldError("username", "账号名称不能为空");
}
}