Struts 2的一个Action中可能包含了多个处理逻辑,当一个Action类中包含多个类似于execute的方法时,每个方法都是一个处理逻辑。不同的处理逻辑可能需要不同的校验规则,Struts 2允许为不同控制逻辑指定不同校验规则的支持。
当需要让一个Action可以处理多个请求时,应该在配置该Action时指定method属性。通过这种方式,就可以将一个Action处理类配置成多个逻辑Action。
在上面的Action类中增加一个login方法,该login方法不做任何处理,只是简单地返回success字符串。下面在struts.xml文件中将该Action类配置成两个逻辑Action。配置这两个逻辑Action的配置片段如下。
程序清单:codes\04\4.2\overrideRule\WEB-INF\src\struts.xml
<!--配置一个名为*Pro的Action,
对应的处理逻辑为RegistAction的{1}方法-->
<action name="*Pro" class="org.crazyit.app.action.RegistAction"
method="{1}">
<result name="input">/WEB-INF/content/form.jsp</result>
<result>/WEB-INF/content/show.jsp</result>
假设上面两个Action的校验规则不同,注册时的校验规则还是之前的校验规则,但登录的校验规则需要增加的用户名和密码相同(这只是假设,实际应用中可能需要密码和重复密码相同,但不会要求用户名和密码相同)。
如果按之前的方式来指定校验规则文件,这个校验规则文件肯定分不清楚到底要校验哪个处理逻辑。为了能精确控制每个校验逻辑,Struts 2允许通过为校验规则文件名增加Action别名来指定具体需要校验的处理逻辑。即采用如下的形式:
<ActionClassName>-<ActionAliasName>-validation.xml
其中ActionClassName是Action处理类的类名,而ActionAliasName就是在struts.xml中配置该Action时所指定的name属性。例如,如果我们需要为loginPro逻辑Action单独指定校验规则,则校验文件的文件名为RegistAction-loginPro-validation.xml(该文件也需要与RegistAction的class文件放在同一路径下),该文件的内容如下。
程序清单:codes\04\4.2\overrideRule\WEB-INF\src\org\crazyit\app\action\RegistAction-loginPro-validation.xml
<?xml version="1.0" encoding="GBK"?>
<!-- 指定Struts 2配置文件的DTD信息 -->
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.3//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd">
<!-- 校验规则文件的根元素 -->
<validators>
<!-- 校验name属性 -->
<field name="name">
<!-- 使用表达式校验器校验name属性 -->
<field-validator type="fieldexpression">
<!-- 指定name属性和pass属性必须相等 -->
<param name="expression"><![CDATA[(user == pass)]]></param>
<message key="nameexp"/>
</field-validator>
</field>
</validators>
上面的校验规则文件仅仅指定了Action的name属性必须和pass属性相同,那么系统中原有的校验规则对loginPro Action是否依然有效呢?
上面使用了表达式校验器,关于各校验器的具体用法,请参阅下一节的介绍。
本应用原来的表单页稍作修改,让该表单页具有两个按钮,一个“登录”提交按钮提交到loginPro,另一个“注册”提交按钮提交到registPro。如果用户单击“登录”提交按钮,该表单将会提交到loginPro Action,那么上面指定的RegistAction-loginPro-validation.xml校验规则就会起作用了。如果校验失败,看到如图4.17所示的校验失败页面。
图4.17 增加校验规则
从图4.17中可以看出,RegistAction-validation.xml文件中的校验规则,依然会对名为loginPro的Action起作用。实际上,名为loginPro的Action中包含的校验规则是RegistAction-validation.xml和RegistAction- loginPro-validation.xml两个文件中规则的总和。
除此之外,还有一种情形——如果系统中包含了两个Action:BaseAction和RegistAction,其中RegistAction继承了BaseAction,且两个Action都指定了对应的配置文件,则RegistAction对应Action的校验规则实际上是RegistAction-validation.xml和BaseAction-validation.xml两个文件中规则的总和。
假设系统有两个Action:BaseAction和RegistAction,则系统搜索规则文件顺序如下:
(1)BaseAction-validation.xml
(2)BaseAction-别名-validation.xml
(3)RegistAction-validation.xml
(4)RegistAction-别名-validation.xml
这种搜索与其他搜索不同的是,即使找到第一个校验规则,系统还会继续搜索,不管有没有这4份文件,也不管是否找到配置文件,系统总是按固定顺序搜索。
假如系统的struts.xml文件中有如下配置片段:
<!-- 将RegistAction的login方法配置成一个逻辑Action -->
<action name="loginPro" class="org.crazyit.app.action.RegistAction" method="login">
...
</action>
如果上面的RegistAction类还继承了BaseAction类,那么上面这个名为login的Action的校验规则是BaseAction-validation.xml、BaseAction-loginPro-validation.xml、RegistAction-validation.xml和RegistAction-loginPro-validation.xml 4份规则文件里规则的总和。
注意:
Struts 2搜索规则文件是从上而下的,实际用的校验规则是所有校验规则的总和。如果两个校验文件中指定的校验规则冲突,则后面文件中的校验规则取胜。