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}">