数据验证:
输入验证分为客户端验证与服务器端验证。客户端验证主要通过JavaScript脚本进行,而服务器端验证主要是通过Java代码进行验证。
分为以下四种情况:
(1)手工编写代码,对Action中所有方法执行前的验证:
自定义的Action要继承自ActionSupport,并且覆盖validate方法,覆盖的方法如下:
@Override public void validate() { if (name == null || "".equals(name)) { //当fieldErrors集合的size()大于0时,会自动跳转你到input视图 this.addFieldError(name, "用户名不能为空"); } if (mobile == null || "".equals(mobile)) { this.addFieldError(mobile, "手机号不能为空"); } else if (!Pattern.matches("^1[34578]\\d{9}$", mobile)) { this.addFieldError(mobile, "手机号码格式不正确!"); } }
注意:ActionSupport类中有个addFieldEorror方法,它调用的是ValidationAwareSupport类中的addFieldEorror方法,方法如下:
public synchronized void addFieldError(String fieldName, String errorMessage) { //相当于一个属性name,可以对应多个错误信息errorMessage final Map<String, List<String>> errors = internalGetFieldErrors(); List<String> thisFieldErrors = errors.get(fieldName); if (thisFieldErrors == null) { thisFieldErrors = new ArrayList<String>(); errors.put(fieldName, thisFieldErrors); } thisFieldErrors.add(errorMessage); }
其中,internalGetFieldErrors()初始化了一个LinkedHashMap类型的fieldErrors,如果这个集合不为空,则会自动跳转到input视图。因此要在struts2.xml中配置input视图,同数据类型转换中数据回显时的配置。
表单提交的前端代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <html> <head> <title>index page</title> </head> <body> <s:fielderror/> <form action="test/login_doSome.action" method="POST"> 用户名:<input type="text" name="name"/><br> 手机号码:<input type="text" name="mobile"/><br> <input type="submit" value="提交"/> </form> <!-- 数据回显怎么解决??? --> </body> </html>
注意:<s:fielderror/>即可
(2)手工编写代码,对Action中指定方法执行前的验证:
同第一种情况相比,只需要改变validation方法的名称,其他均不变,代码如下:
public void validateDoSome() { if (name == null || "".equals(name)) { //当fieldError集合的size()大于0时,会自动跳转你到input视图 this.addFieldError(name, "用户名不能为空"); } if (mobile == null || "".equals(mobile)) { this.addFieldError(mobile, "手机号不能为空"); } else if (!Pattern.matches("^1[34578]\\d{9}$", mobile)) { this.addFieldError(mobile, "手机号码格式不正确!"); } }
此例是验证执行方法doSome,因此命名方式是validateDoSome。
(3)基于XML配置方式,对Action中所有方法执行前的验证:
在Action类所在的包中放入一个XML配置文件,该文件的取名应遵守 ActionClassName-validation.xml 规则。该文件的文件头部,需要配置约束,该约束可以在xwork-core-2.3.24.jar的根下xwork-validator-1.0.3.dtd中可以找到。该文件代码如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> <validators> <field name="name"> <field-validator type="requiredstring"> <!-- <param name="trim">true</param> --> <message>用户名不能为空!</message> </field-validator> </field> <field name="mobile"> <field-validator type="requiredstring"> <message>手机号不能为空!</message> </field-validator> <field-validator type="regex"> <param name="regex"><![CDATA[^1[34578]\d{9}$]]></param> <message>手机号格式不正确!</message> </field-validator> </field> </validators>
解析:<field name="name">,对应的是需要验证的属性;
<field-validator type="requiredstring">,对应的是验证器类型,在xwork-core-2.3.24.jar的com.opensymphony.xwork2.validator.validators的根下default.xml中可以找到所有验证器类型
<param name="regex"><![CDATA[^1[34578]\d{9}$]]></param>,对应的是验证器类中的属性,查找相应的类即可知道,前面注释掉的代码,是因为trim属性默认是true,所以不用写了。
<message>手机号格式不正确!</message>,对应错误提示信息。
(4)基于XML配置方式,对Action中指定方法执行前的验证:
将上述文件的取名该为,遵守 ActionClassName-ActionName-validation.xml 规则,比如LoginAction-login_doSome-validation.xml。其他均不变。
补充:
(1)常用验证器用法(引用自北京动力节点):
(2)输入验证的执行流程:
若以上四种输入验证方式均进行了设置,则其执行顺序如下:
首先执行基于XML的验证,系统按照 ActionClassName-validaition.xml 、 ActionClassName-ActionName-validaition.xml 的顺序寻找校验文件,也就是说后者会覆盖前者;接下来,执行Action中的validateXxx()方法,执行Action中的validate()方法,前者的优先级高。
(3)Action类的执行原理及顺序:
(1)类型转换:
类型转换失败实在Action调用相应属性的set方法之前发生的,类型转换失败,不影响程序的运行。
(2)set方法:
无论类型转换是否成功,都将执行该属性的set方法。只不过,类型转换失败,会设置该属性值为null。
(3)数据验证:
若对于类型转换失败的数据,程序中存在为null的验证,则会在向fieldErrors集合中加入类型转换异常信息的同时,将该属性为null的验证信息也加入fieldErrors集合.
(4)Action方法:
只有当fieldErrors集合的size为0,即没有异常信息时,才会执行Action方法。