.Java程式設計師從笨鳥到菜鳥之(四十一)細談struts2(五)action基礎知識和資料校驗
一:首先看一下struts2中action的實現方式:
1.建立普通的pojo類:這種方式能夠實現簡單的action功能,但struts2內自帶的一些驗證和其他功能不能夠實現
2.繼承ActionSupport類實現action,因為ActionSupport已經實現了Action介面,還實現了Validateable介面,提供了資料校驗功能。通過繼承該ActionSupport類,可以簡化Struts 2的Action開發。
3.實現action介面,這個接口裡面定義了一些action所要實現的功能的標準,但驗證等功能沒有,所以一般還是繼承actionsupport來實現action
Action 跟
當我們在寫action的時候,可以實現Action介面,也可以繼承Actionsupport這個類.到底這兩個有什麼區別呢?
Action介面有:
public static final java.lang.String SUCCESS = "success"; public static final java.lang.String NONE = "none"; public static final java.lang.String ERROR = "error"; public static final java.lang.String INPUT = "input"; public static final java.lang.String LOGIN = "login"; public abstract java.lang.String execute() throws java.lang.Exception;
而Actionsupport這個工具類在實現了Action介面的基礎上還定義了一個validate()方法,重寫該方法,它會在execute()方法之前執行,如校驗失敗,會轉入input處,必須在配置該Action時配置input屬性。
另外,Actionsupport還提供了一個getText(String key)方法還實現國際化,該方法從資原始檔上獲取國際化資訊.
這樣在自定義標籤時可以定義一個變數為new actionsupport物件實現國際化。
ActionSupport類的作用
struts2不要求我們自己設計的action類繼承任何的struts基類或struts
Struts2中通常直接使用Action來封裝HTTP請求引數,因此,Action類裡還應該包含與請求引數對應的屬性,並且為屬性提供對應的getter和setter方法。
二.action資料校驗
在上面應用中,即使瀏覽者輸入任何使用者名稱、密碼,系統也會處理使用者請求。在我們整個HelloWorld應用中,這種空使用者名稱、空密碼的情況不會引起太大的問題。但如果資料需要儲存到資料庫,或者需要根據使用者輸入的使用者名稱、密碼查詢資料,這些空輸入可能引起異常。為了避免使用者的輸入引起底層異常,通常我們會在進行業務邏輯操作之前,先執行基本的資料校驗。
Action資料校驗功能是struts2給我們提供的一個伺服器端簡單驗證的功能,這個功能使我們簡化了一些沒必要的程式碼。下面看一下具體實現:
1.繼承ActionSupport
ActionSupport類是一個工具類,它已經實現了Action介面。除此之外,它還實現了Validateable介面,提供了資料校驗功能。通過繼承該ActionSupport類,可以簡化Struts 2的Action開在Validatable介面中定義了一個validate()方法,重寫該方法,如果校驗表單輸入域出現錯誤,則將錯誤新增到ActionSupport類的fieldErrors域中,然後通過OGNL表示式負責輸出為了讓Struts 2增加輸入資料校驗的功能,改寫程式中的LoginAction,增加重寫validate方法。下面看一下具體程式碼實現:
package com.bzu.action;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public void validate() {
if("".equals(username))
this.addActionError("soory,the username can't blank");
if("".equals(password))
this.addActionError("soory,the password can't blank");
}
public String execute(){
if(username.equals("admin")&&password.equals("123456"))
return "success";
return "fail";
}
}
這裡簡單的實現了表單資料驗證功能,上面的Action類重寫了validate方法,該方法會在執行系統的execute方法之前執行,如果執行該方法之後,Action類的fieldErrors中已經包含了資料校驗錯誤,請求將被轉發到input邏輯檢視處。但還是要注意以下幾點:
1.在實現表單驗證功能的時候一定不要忘記了在struts.xml中相對應的action中配置result=“input”,因為表單驗證失敗預設返回的字串為input,如果沒有的話會找不到這個結果而報錯。
2.資料驗證中,如果資料不符的時候可以報三種錯誤,我們上面程式碼中只是列舉了action錯誤,另外兩種是Field欄位的錯誤,還有一種就是actionMessage。
3.注意在顯示介面接收action錯誤時,要在想顯示錯誤的地方加上<s:actionerror/>標籤,如果想接收Filed域的錯誤時,一定要用struts標籤,如果不用的話是不會顯示欄位錯誤的
2.使用Struts 2的校驗框架
上面的輸入校驗是通過重寫ActionSupport類的validate方法實現的,這種方法雖然不錯,但需要大量重寫的validate方法——畢竟,重複書寫相同的程式碼不是一件吸引人的事情。類似於Struts 1,Struts 2也允許通過定義配置檔案來完成資料校驗。Struts 2的校驗框架實際上是基於XWork的validator框架。下面還是使用原來的Action類(即不重寫validate方法),卻增加一個校驗配置檔案,校驗配置檔案通過使用Struts 2已有的校驗器,完成對錶單域的校驗。Struts 2提供了大量的資料校驗器,包括表單域校驗器和非表單域校驗器兩種。本應用主要使用了requiredstring校驗器,該校驗器是一個必填校驗器——指定某個表單域必須輸入。下面是校驗規則的定義檔案:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<field name="username">
<field-validator type="requiredstring">
<param name="trim">false</param>
<message>username can't be blank!</message>
</field-validator>
<field-validator type="stringlength">
<param name="minLength">4</param>
<param name="maxLength">6</param>
<param name="trim">false</param>
<message key="username.invalid"></message>
</field-validator>
</field>
<field name="password">
<field-validator type="requiredstring">
<message>password can't be blank!</message>
</field-validator>
<field-validator type="stringlength">
<param name="minLength">4</param>
<param name="maxLength">6</param>
<message>length of password should be between ${minLength} and ${maxLength}</message>
</field-validator>
</field>
<field name="age">
<field-validator type="required">
<message>age can't be blank!</message>
</field-validator>
<field-validator type="int">
<param name="min">10</param>
<param name="max">40</param>
<message>age should be between ${min} and ${max}</message>
</field-validator>
</field>
</validators>
定義完該校驗規則檔案後,該檔案的命名應該遵守如下規則:
ActionName-validation.xml:其中ActionName就是需要校驗的Action的類名。因此上面的校驗規則檔案應該命名為“LoginAction-validation.xml”,且該檔案應該與Action類的class檔案位於同一個路徑下。因此,將上面的校驗規則檔案放在WEB-INF/classes/lee路徑下即可。當然,在struts.xml檔案的Action定義中,一樣需要定義input的邏輯檢視名,將input邏輯檢視對映到login.jsp頁面。在這種校驗方式下,無需書寫校驗程式碼,只需要通過配置檔案指定校驗規則即可,因此提供了更好的可維護性。
三、action中的執行方法
Action中預設的執行方法是execute方法,這個方法執行請求,然後轉向其他的頁面,這是常規的做法,但有時候我們不想用這個方法名,為了程式碼的可讀性,我們希望讓他執行我們自己定義的方法,下面我們就來看一下執行其他方法的兩種方法:
1.在struts.xml配置method屬性
其實執行execute方法是對應action在配置檔案method的預設方法,所以要想執行其他的方法,我們可以修改這裡的預設方法,只要把預設的方法改為我們自定義的方法就可以了。部分配置程式碼:
<action name="LoginAction" class="com.bzu.action.LoginAction" method="login">
<result name="success">success.jsp</result>
<result name="fail">fail.jsp</result>
<result name="input">login.jsp</result>
</action>
<action name="RegisteAction" class="com.bzu.action.LoginAction" method="registe">
<result name="success">success.jsp</result>
<result name="fail">fail.jsp</result>
<result name="input">login.jsp</result>
</action>
2.DMI(動態直接呼叫)這種方法,不需要進行struts.xml的配置。而是在html或者jsp頁面中通過標示符號指定了要呼叫的方法。 關鍵的標示符號為"!"號,具體看一下下面表單:
<s:form action="LoginAction!login">
<s:actionerror/>
username:<s:textfield name="username"></s:textfield>
password:<s:password name="password"></s:password>
<s:submit value="提交"></s:submit>
</s:form>
3.提交按鈕指定提交方法,普通的提交按鈕我們會這麼寫:<s:submitvalue="提交"></s:submit>
當我們想提交到我們指定的方法時我們可以在這個標籤裡新增一個method屬性指定要提交的方法,如下:
<s:submit value="提交" method="login"></s:submit>
4.使用萬用字元配置Action,這種方法可以解決action配置檔案混亂的問題,減少action的配置:
<action name="helloworld_*" class="com.bird.action.HelloWorld" method="{1}">
<result name="success">/WEB-INF/jsp/{1}_success.jsp</result>
</action>
在name屬性的值後面加上*,意思是隻要你請求的action名字以helloworld開頭,本action就是你找的action,然後method是大括號加上1,這個1代表第一個星號的值,這樣就可以動態執行請求的方法。
最後說一點,有時候使用者在位址列隨便輸入的時候,找不到對應的action,直接對報出一些錯誤,這樣的介面一般都很難看,所以為了能給使用者一個友好的提示介面,一般我們會再struts.xml檔案配置預設的action,程式碼如下: