在本实例我们包含如何验证在表单字段输入使用 Struts 2的 XML验证技术.在 之前的学习中我们讨论了在Action类的validate方法进行表单验证. 使用分离的 XML验证文件可以使用 Struts 2 框架内置的验证器的验证能力.
之前我们学习了在代码写验证,但是如果验证规则变了,要修改代码,不灵活,因而struts2提供了基于xml验证规则,使用struts的内置验证器来执行验证
要验证用户表单输入你可以使用一个分离的包含验证规则的 XML文件.包含验证规则的XML文件 名字必须是 ActionClassName-validation.xml. 在该实例应用 , XML验证文件名字命名为 EditAction-validation.xml (查看 src/main/resources/org/apache/struts/edit/action 对于Maven 实例或 src/org/apache/struts/edit/action对于 Ant实例).
在 -validation.xml文件中有两种方式定义:
<validator>
<field-validator>
非字段验证器: 元素允许你声明两种验证器 (普通 验证器和字段验证器).
<validator type="expression> <param name="expression">foo gt bar</param> <message>foo must be great than bar.</message> </validator> <validator type="required"> <param name="fieldName">bar</param> <message>You must enter a value for bar.</message> </validator>
字段验证器: 元素基本上与 元素系统只是 fieldName 属性从包含它的 元素继承. 定义在 元素中字段验证器将自动 设置fieldName属性值与父 元素的 fieldName 属性值相同.
使用 语法声明字段验证器:
<field name="email_address">
<field-validator type="required">
<message>You cannot leave the email address field empty.</message>
</field-validator>
<field-validator type="email">
<message>The email address you entered is not valid.</message>
</field-validator>
</field>
两种方式验证email
<field name="email_address">
<field-validator type="required">
<message>You cannot leave the email address field empty.</message>
</field-validator>
<field-validator type="email">
<message>The email address you entered is not valid.</message>
</field-validator>
</field>
<validator type="required">
<param name="fieldName">email_address</param>
<message>You cannot leave the email address field empty.</message>
</validator>
<validator type="email">
<param name="fieldName">email_address</param>
<message>The email address you entered is not valid.</message>
</validator>
可以短路验证器栈. 这里是另外一个验证规则配置: 注意一些 和 元素设置了short-circuit 属性为 true.
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
<!-- Field Validators for email field -->
<field name="email">
<field-validator type="required" short-circuit="true">
<message>You must enter a value for email.</message>
</field-validator>
<field-validator type="email" short-circuit="true">
<message>Not a valid e-mail.</message>
</field-validator>
</field>
<!-- Field Validators for email2 field -->
<field name="email2">
<field-validator type="required">
<message>You must enter a value for email2.</message>
</field-validator>
<field-validator type="email">
<message>Not a valid e-mail2.</message>
</field-validator>
</field>
<!-- Plain Validator 1 -->
<validator type="expression">
<param name="expression">email.equals(email2)</param>
<message>Email not the same as email2</message>
</validator>
<!-- Plain Validator 2 -->
<validator type="expression" short-circuit="true">
<param name="expression">email.startsWith('mark')</param>
<message>Email does not start with mark</message>
</validator>
</validators>
短路和验证器风格
非字段验证器优先于字段验证器. 非字段验证器按照定义顺序执行然后执行按定义顺序执行字段验证器.标记为短路的验证器将阻止后续验证并把一个错误(action 错误或字段错误取决于验证器的类型) 添加到 ValidationContext.
在上面的例子中, 验证的真实执行流程如下:
Plain Validator 1
Plain Validator 2
Field Validators for email field
Field Validators for email2 field
短路和验证器风格
如果一个字段验证器短路仅仅阻止其它字段验证器对该字段继续的验证.例如如下的例子 -validation.xml file:
<validator type="required" short-circuit="true">
<param name="fieldName">bar</param>
<message>You must enter a value for bar.</message>
</validator>
<p/>
<validator type="expression">
<param name="expression">foo gt bar</param>
<message>foo must be great than bar.</message>
</validator>
两个验证都会被执行, 尽管 “required” 验证器是短路的. “required” 验证器是字段验证器因而不能短路非字段验证器ExpressionValidator ,字段验证器只能短路相同字段的字段验证器.
字段验证器, 正如名字暗示, 只作用于action的一个字段.
注意
非字段验证器优先于字段验证器,与它们在 *-validation.xml中定义的顺序无关.
每个验证器或字段验证器元素 必须在验证器元素内部定义一个消息元素 . 该消息元素有一个属性 key,该属性是可选的 . 消息标签的标签体内容作为默认消息 添加到Action如果验证失败.
还是之前练习的项目,我们来验证一下字段
当用户提交该表单时, 我们想验证他在表单中的输入.
在Action相同包下新建:Action名-validation.xml文件:
编辑:
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<!-- 以上内容,根据使用版本的不同,有可能会引发错误 -->
<validators>
<validator type="requiredstring">
<param name="fieldname">personBean.firstName</param>
<message key="personBean.firstName.required"></message>
</validator>
<validator type="requiredstring">
<param name="fieldname">personBean.lastName</param>
<message>Last name is required.</message>
</validator>
<!-- <validator type="required"> <param name="fieldname">personBean.age</param> <message>Age is required.</message> </validator> <validator type="fieldexpression"> <param name="fieldname">personBean.age</param> <param name="expression"><![CDATA[personBean.age > 18]]></param> <message>Age must > 18 </message> </validator> -->
<!-- 字段验证器 -->
<field name="personBean.age">
<field-validator type="required" short-circuit="true">
<message>ID必填的</message>
</field-validator>
<field-validator type="int">
<param name="min">18</param>
<param name="max">90</param>
<message>age必须在 ${min} 到 ${max} 之间</message>
</field-validator>
</field>
<field name="personBean.email">
<field-validator type="requiredstring" short-circuit="true">
<message key="personBean.email.required"></message>
</field-validator>
<field-validator type="email">
<!-- 使用了国际化方式 -->
<message key="personBean.email.format"></message>
</field-validator>
</field>
<!-- 非字段验证器 <validator type="requiredstring"> <param name="fieldname">personBean.email</param> <message>Email is required.</message> </validator> -->
</validators>
说明:
1、如果同时xml验证文件和代码验证,先调用xml验证,然后调用代码验证
2、类似于validateXx只验证xx方法,我们也可以使用定义方法专用验证文件,比如只想对xx验证
RegisterAction-xx-validation.xml,而 RegisterAction-validation.xml类似于validate方法对所有Action方法起作用
注意:这里的xxx指的是struts.xml中的action标签的name
3、每个验证器类型都对应一个类,我们称之为内置验证器,它们配置在:
测试:
实际项目开发,我们都会前端验证和后端验证搭配使用
为了给用户更好体验,通常采用Ajax来执行服务器端验证效果,而不是整体提交后验证
为了灵活,我们尽力用xml格式验证