action是struts2中编程的中心单元,持有数据并且执行逻辑。同时还提供validation,错误信息处理等便利。本文描述action和validation如何配合、如何协同。这些协同很多都是以name匹配的方式来完成的,所以我们首先来看看action和validation各自的命名方式,然后再把二者联系起来。
1. wildcard mapping
在struts2中,对action-mapping引入了wildcard机制。wildcard-mapping包括class层的、method层的、参数层的,个人感觉method层实用中会更多见一些。下面是一个wildcard method的例子。来自官网。
在struts.xml文件中
- <action name="*Crud" class="example.Crud" method="{1}">
- <action name="Crud_*" class="example.Crud" method="{1}">
有访问来到并且满足name="*Crud"的映射时,框架会自动为该mapping创建一个新的action name,引用该class中的 * method。返回的result中也能使用wildcard,例如
- <action name="*Text"
- class="TextMngAction"
- method="{1}">
- <result name="success">{1}Text.jspresult>
- <result name="input">editText.jspresult>
- </action>
下面来看看vaildation
2. validation
struts2中的validation主要有4个基本途径:
1 validate()
2 validateXxx()
3 validation 配置class-validation.xml
4 validation 配置class-alias-validation.xml
前两种方式通过在action中声明并实现一个method来完成,后面两个则是运用validation框架。1和2方式下,同<action></action>的配置基本不存在配合的问题,validate()是调用这个action的任何逻辑动作前都会执行,validatXxx()是在调用这个action的Xxx()方法前被执行,他们的配合基本同配置无关,在一个java文件中完成配合。 后两种方式则牵涉到多个文件的配置。
第一,后两种方式需要为每个action class建立一个xml文件,并且这些xml文件将放在action的java旁边,也就是同一个package目录下。
第二,validation.xml中编写的内容大致为
- <validators>
- <field name="text.id">
- <field-validator type="requiredstring">
- <message key="text.id">message>
- field-validator>
- <field-validator type="regex">
- <param name="expression">
- param>
- <message key="text.id.length">must be 4 digitmessage>
- </field-validator>
- </field>
- </validators>
其含义为对text属性的id字段进行检测,例子中要求该字段不能为空,且内容必须是4位数字。关于field-validator 的类型,大家可以参考官网。检查不通过时,出错信息在<message></message>中表示。 key是要求要到资源文件中所搜取的,如果搜不到,则用<message></message>中的内容直接显示。关于资源文件的设置和用法,本文不涉及。
第三,validation.xml文件的命名有两种方式,即class-validation.xml和class-alias-validation.xml。其中的class就是该Action的类名(不含.class),alias就是action-name。需要注意的是,class-validation.xml在调用该class的任何方法时都会起作用,class-alias-validation.xml则仅在和alias中的action-name相同时才起作用。如果你希望某个action到来时,仅有class-alias-validation.xml发生作用,那是做不到的。所以在class-validation.xml只能放全体method都用的着的验证条件,或者索性不建立class-validation.xml这个文件,而只使用class-alias-validation.xml。
3. 二者的配合
这里要指出官网文档中的一个错误,
- To use a postfix wildcard, just move the asterisk and add an underscore.
- <action name="Crud_*" class="example.Crud" method="{1}">
- From the framework's perspective, a wildcard mapping creates a new "virtual" mapping with all the same
- attributes as a conventional, static mapping. As a result, you can use the expanded wildcard name as the name
- of validation, type conversion, and message resource files, just as if it were an Action name (which it is!).
- Crud_input-validation.xml
- Crud_delete-conversion.xml
按官网的说法,validation.xml可以命名成actionName-validation.xml(如果我们把上面的Crud_理解成name="Crud_"中的Crud)或者class_method-validation(如果我们把Crud理解成class="example.Crud"中的Crud)。但经实际验证,这种命名方式是不起作用的。成功的命名方式是Crud-Crud_input-validation.xml这种形式。即按照class-alias-validation.xml这种格式,class是action的类名,alias是整个wild mapping后的结果。
大家看到了,Crud-Crud_input-validation.xml显得比较啰嗦,即使同时出现两个Crud,我也不希望连续出现。所以在我看来,通常在配置<action>时应该使用*前置的方式。
- <action name="*Text" class="TextMngAction" method="{1}">