• 沒有找到結果。

校验框架

在文檔中 第一部分: (頁 174-178)

通过前面的学习,读者现在已经可以编写一个简单的应用。在介绍 action 的时候,我们 提到过使用 validate 方法可以把用于校验的代码从 execute 方法里抽取出来,从而在一定程 度上减轻逻辑的混乱程度。但这还并不能让人满意,那么有没有其它更好的方法来实现校验 呢?其实,Struts2 已经提供了现成的校验框架,用户要做的只是在配置文件中进行校验相 关的适当配置,框架就会实现所期望的校验功能。

通常,只需使用 Struts2 自带的校验器就能满足需求,但是也不排除在某些情况下定制 一个校验器来实现特定的功能。本章我们将介绍 Struts2 框架校验的知识,包括使用默认的 校验器以及创建自己的校验器。

10.1 使用 Struts2 自带的校验器

我们知道,Validate 方法实现校验的原理是当程序执行到 action 时先判断这个 action 有 没有实现 validate 方法,如果已经实现了,那么就先执行 validate 方法,然后再执行 execute 方法;如果还没有实现,那么就直接执行 execute 方法。

Struts2 框架自带的校验功能是通过配置文件实现的。它的原理是当程序执行到 action 但是还没有执行到 action 里的方法时将其拦截,转而执行校验器,校验器执行完再返回到 action 继续执行。

从上面的原理可以看出要实现框架校验功能,必须要做两件事情:第一,给 action 配置 拦截器,这个拦截器必须能让 action 被暂停,然后转而执行校验器部分;第二,给 action 配 置校验器,通过该配置文件找到对应的校验器以实现校验功能。

10.1.1 配置拦截器

首先让我们来看一下如何给 action 配置拦截器。这个在第四章里已经系统地讲过,这里 要注意的是应该给 action 配置哪个拦截器。要实现框架校验功能,就要给 action 配上 validation 这个拦截器,由它打开校验提交到 action 中的字段的功能。所以只要在 Struts.xml 里对应的 action 标签下添加如下代码就能打开 Struts2 的校验功能了:

<interceptor-ref name="validation" />

<result name="input" >……</result>

其中,第一行是指引用“validation”这个拦截器,也就是相当于实现打开校验器功能。

第二行是当该拦截器失败或者校验器失败时将要跳转到的地方,这里需要注意的是 result 的 name 属性为“input”。

通常在使用 Struts2 的框架校验功能的时候,还会配合其它的拦截器使用,也就是说还 要再打开其它的拦截器。因此可以使用 Struts2 为我们封装的拦截器栈,而且一般都是这么 做的,所以在实际的应用中,通常都会看到下面的代码而不是上面给的代码:

<interceptor-ref name="completeStack" /> <!--这里使用了 completeStack 这个拦截器栈-->

<result name="input" >……</result>

这们也可以使用其它的拦截器栈,比如 validationWorkflowStack,它将 validation 和 workflow 这两个拦截器进行了封装。这样就为使用校验器做好了准备,下面就让我们来看 校验器的实现部分。

10.1.2 配置校验器

一般情况下都使用第一种方式,比如有一个 action 叫 LogginAction.java,现在要给它配 置校验器,那么校验配置文件的名字就应该是 LogginAction-validation.xml。接下来就让我们 来看看校验配置文件的内容。

首先,在配置文件的前端需要添加下列语句:

<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"

"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

这是 Struts2 的要求,是对 validator 的约束。

注意:对应于不同的版本,Struts2 对该 dtd 文件的版本要求也是不一样的。此处可以看到,

对于我们使用的 Struts2-2.0.9 版本,该 dtd 文件版本要求是 xwork-validator-1.0.2。

接着,给 action 中的字段配置校验器。比如 LogginAction.java 里有属性 username 和 password,那么配置文件 LogginAction-validation.xml 里对这两个属性的校验配置如下:

<validators> Field Validator),而使用在 password 字段上的方式叫做“非字段校验”(即 Non-Field Validator),它们的区别是一个使用<field>标签进行声明,一个使用<valuator>标签进行声明。

<param name=”fieldName”> </param>则不是必须,这是因为普通校验器只返回 action 级的 错误。

Struts2 提供的字段校验器有:required validator 、requiredstring validator 、int validator 、 date validator 、expression validator 、fieldexpression validator 、email validator 、url validator 和 stringlength validator 等等,可在字段校验方式以及非字段校验方式下使用;普通校验器 有:expression validator,只能在非字段校验方式下使用;此外还有 visitor validator 以及 short-circuiting validator,可在字段校验方式和非字段校验方式下使用。它们的功能如下表 10-1 所示:

表 10-1 各校验器的功能说明

名称 功能

required 校验指定字段是否为空

requiredstring 校验指定字符串字段非空

int 校验指定整数字段是否在一个范围内

date 校验指定的日期是否在一个范围内

expression 校验指定的表达式是否为真

fieldexpression 校验指定 OGNL 表达式字段

email 校验一个指定的字符字段如果非空是否是一个合法邮箱地址

url 校验一个指定的字段是否是字符串并且合法

visitor 将当前校验推送到另一相关校验

conversion 校验指定字段是否发生转换错误

stringlength 校验指定字段是否发生转换错误

reqex 校验指定使用正规表达式的字符字段

非字段校验方式配置的校验器比字段校验方式配置的校验器的执行优先级高。Struts2 在执行的时候是先按照定义的顺序执行非字段校验方式配置的校验器,然后再按照定义的顺 序执行字段校验方式配置的校验器。这里还要注意的是关于短路校验器(short-circuiting validator)的使用,它能打断校验器的执行。短路校验器的使用方式是如下:

<validator type="requiredstring" short-circuit="true"> <!--将该校验器设置为短路-->

<param name="fieldName">age</param> <!--对 age 字段校验-->

<message>not null</message>

</validator>

或者:

<field name="confirm"> <!--对 confirm 字段校验-->

<field-validator type="fieldexpression" short-circuit="true"> <!--将该校验器设置为短路-->

<param name="expression">(password==confirm)</param>

<message><![CDATA[ confirm must be the same as the password if specified ]]></message>

</field-validator>

下面让我们来看一个特殊的校验器—visitor validator 。这个校验器能把 action 里的一个 对象的校验推送到这个对象的类的校验配置,然后利用为该对象的类所配置的校验器来校验 该对象的属性。它的使用方式如下:

<validators> 配置方式则不需要;context 指校验会发生的 context,是可选的;appendPrefix 指要添加到字 段上的前缀,也是可选的。

在上面的例子中,我们可以很方便对同一类对象进行统一校验,这样当有一个类的多个 实例化对象,而且又需要对这几个对象进行校验的时候,那么使用这个校验器将这些相同类 的对象都推送到这个类的校验配置文件中去校验会在很大程度上提高工作的效率。不然,就 需 要 为 各 个 action 配 置 相 同 属 性 才 能 达 到 相 同 的 目 的 。 对 于 上 面 一 段 代 码 , 由 于

“appendPrefix”设为 true,所以 Struts2 会把这里的字段名“user”加到它的属性之前,比 如 user 有属性 tel,那么即得到 user.tel,又由于对象 user 是 User.java 的实例,所以这样就会 找到 User-validation.xml 这个校验配置文件进行校验。由于这里“context”属性的值为 myContext,所以也会寻找 User-myContext-validation.xml 这个文件。

10.1.3 自带校验器实例

通过上面的介绍,相信读者已经能使用 Struts2 的自带校验器来实现需要的功能了。下 面就让我们一起来实现一个完整的实例,让读者对自带校验器的使用有一个更加深刻的认 识。

在这个例子中我们使用了普通校验器 expression validator,运行后将会看到当将 visitor validator 设置为 short-circuit=”true”时,只能得到一个 actionerror,所有在这个校验器后面 的其它校验器都将不会被执行。对 confirm 字段我们使用了两个字段校验器,分别是 requiredstring 和 stringlength 校验器,其中 requiredstring 被设置成 short-circuit=”true”,运 行 后 将 会 看 到 当 输 入 不 符 合 requiredstring 时 stringlength 将 不 被 执 行 , 当 输 入 符 合 requiredstring 但不符合 stringlength 时两个校验器都会被执行。这里还使用了一个 visitor 校 验器,将 user 的校验推送到 User-validation.xml 去校验,这在大型的应用中非常有优势。

首先,新建一个项目,这里命名为“BaseinValidator”,然后在“构建路径”下添加所需 的 Jar 包,导入所需要的包,这里只需要导入 Struts2 的 Jar 包。在 src 下新建包 eshop,创建 文件,这里新建的文件如下图,最后建好的文件结构如下图 10-1 所示:

图 10-1 BaseinValidator 结构 下面让我们看看各个文件的具体内容。

首先来看配置文件 Web.xml,该文件主要用来配置过滤器,代码如下:

在文檔中 第一部分: (頁 174-178)