對於開發Struts2應用的開發者來講,Action纔是應用的核心,咱們經過開發不一樣的業務控制器—Action來處理不一樣的用戶請求邏輯。jsp
實現Action類測試
Struts2採用了低入侵式的、鬆耦合設計,開發一個Action類,不須要繼承或實現任何Struts2的類或接口。url
咱們先來看一下標準的Action類的格式:spa
public class 類名 {設計 private String 屬性1;orm private String 屬性2;xml ... ...對象 屬性對應的get和set方法繼承
public String execute() throws Exception {接口 return 邏輯視圖字符串; } } |
從上面的結構中咱們能夠看出這與普通的POJO沒有多大區別,惟一的區別就是Action類必須包含一個無參數的、返回字符串的execute()方法。而Action的屬性則是與Action要處理的HTTP請求信息中封裝的參數對應。
在Struts2中提供了一個Action接口和一個ActionSupport類來幫助咱們開發Struts2應用。若是須要咱們能夠繼承他們。
Action接口提供了execute()接口方法和一些經常使用的表示處理邏輯結果的邏輯視圖名。
Action接口結構以下:
public interface Action { public static final String SUCCESS = "success"; public static final String NONE = "none"; public static final String ERROR = "error"; public static final String INPUT = "input"; public static final String LOGIN = "login"; public String execute() throws Exception; } |
實現Action接口可以幫助咱們規範Action的開發,對經常使用的處理結果有着統一規範的做用。
ActionSupport類圍繞請求邏輯處理提供了不少方法,如默認處理用戶請求、數據校驗、錯誤消息、國際化資源等方面。
Action間接訪問ServletAPI
Struts2的Action沒有與任何ServletAPI耦合,這就可以方便的測試Action。可是在開發Web應用中,不訪問ServletAPI是不可能的。在Struts2中提供了一個ActionContext類來幫助咱們訪問ServletAPI。
下面是關於咱們常要訪問ServletAPI的一些方法:
方法名 |
說明 |
public Object get(String key) |
相似於調用HttpServletRequest的getAttribute(String name)方法。 |
public Map<String, Object> getApplication() |
返回一個Map對象,相似於得到ServletContext對象 |
public static ActionContext getContext() |
得到ActionContext實例 |
public Map<String, Object> getParameters() |
相似於調用HttpServletRequest的getParameterMap()方法。 取得值是一個String[]類型的值 |
public Map<String, Object> getSession() |
返回一個Map對象,相似於得到HttpSession對象 |
Action直接訪問ServletAPI
Struts2還提供了兩種方式直接訪問ServletAPI。
一、 實現相應的接口
Struts2提供瞭如下接口來訪問ServletAPI:
接口 |
說明 |
ServletContextAware |
實現該接口,就能夠直接訪問Web應用的ServletContext對象實例。 |
ServletRequestAware |
實現該接口,就能夠直接HttpServletRequest對象實例。 |
ServletResponseAware |
實現該接口,就能夠直接HttpServletResponse對象實例。 |
二、 藉助於ServletActionContext類
在Struts2中還提供了一個ServletActionContext類,來幫助咱們直接訪問ServletAPI。
ServletActionContext類中包含了如下靜態方法幫咱們得到相應的實例對象:
靜態方法名 |
說明 |
PageCotext getPageContext() |
得到PageCotext對象 |
HttpServletRequest getRequest() |
得到HttpServletRequest對象 |
HttpServletResponse getResponse () |
得到HttpServletResponse對象 |
ServletContext getServletContext() |
得到ServletContext對象 |
注意:即便咱們在Struts2的Action中得到了HttpServletResponse對象,也不要嘗試產生對客戶端的輸出內容信息。
配置Action
Struts2使用包來管理Action信息,因此咱們須要在struts.xml文件中使用<action>元素做爲<package>元素的子元素來配置Action信息。
一個完整的Action信息以下格式:
<package name="sample1" extends="struts-default"> <action name="index" class="org.struts2.samples1.HelloWorld"> <result name="success">/index.jsp</result> </action> </package> |
在配置Action信息,class屬性能夠省略,這時默認的實現類爲ActionSupport類。
name屬性:Action的名稱,其屬性值對應着它所處理URL的前半部分。
如:http://localhost://8080/Strurs2Demo/index.action
咱們看到Action類的execute方法在處理完請求邏輯後返回一個字符串,這個字符串只是一個邏輯視圖名,和實際的物理視圖資源沒有任何關聯。爲了讓Struts2可以找尋到請求邏輯後響應的具體物理資源,咱們須要使用<action>元素的子元素<result>元素來表述邏輯視圖與物理視圖資源的關聯關係。
動態方法調用
到目前爲止咱們知道了如何編寫一個Action類,配置Action信息。可是這個Action只能處理一個請求,如何可以像Struts1那樣繼承了DispatchAction後,可以一個Action類處理多個請求邏輯?
在Struts2中是使用動態方法調用技術來解決這個問題的。下面咱們就來看看如何實現的:
爲了讓Struts2開啓動態調用功能,咱們須要將Struts2常量struts.enable.DynamicMethodInvocation的值設置爲true以下:
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant> |
有兩種方式能夠實現動態調用,來達到一個Action類處理多個請求邏輯能。
方式一:爲<action>元素指定method屬性。如:
<action name="login" class=" org.struts2.samples1.LoginRegistAction"> <action name="regist" class=" org.struts2.samples1. LoginRegistAction "> |
可是這樣咱們發現這兩個Action的配置信息絕大部分相同,所以這種配置至關冗餘。爲了解決這個問題,Struts2還提供了另一種形式的動態方法調用。
方式二:使用通配符
在配置Action信息是,咱們須要指定name,class,method屬性,這3個屬性均可支持通配符,這種通配符的方式就是另外一種動態方法調用。
如:
<action name="*Action" class=" org.struts2.samples1.LoginRegistAction"> |
這個配置代表只要以*Action結尾的請求均可以處理。好比aAction.action、abcAction.action。
好比:LoginAction.action請求會被org.struts2.samples1.LoginAction實例的Login方法處理。
<action name="*Action" class="org.struts2.samples1.{1}Action" method="{1}"> |
好比:Book_save.action請求會被org.struts2.samples1.BookAction實例的save方法處理。
<action name="*_*" class="org.struts2.samples1.{1}Action" method="{2}"> |
咱們還能夠經過使用通配符來配置一個可以處理任何請求的通用Action。如:
<action name="*"><result>/{1}.jsp</result></action> |
如今咱們會碰到以下問題:在處理用戶請求時,咱們可以找到多個匹配的、符合條件處理這個請求的Action配置信息,這時怎麼選擇呢?請看下面實例代碼:
<package name="sample" extends="struts-default"> <action name="*" class="org.struts2.samples.OneAction"> <result name="success">/welcome.jsp</result> </action> <action name="*Action" class="org.struts2.samples.TwoAction"> <result name="success">/welcome.jsp</result> </action> <action name="threeAction" class="org.struts2.samples.ThreeAction"> <result name="success">/welcome.jsp</result> </action> </package> |
當請求http://localhost:8888/Struts2Demo/regist.action到達時,咱們能夠看出上述的3個action均可以處理這個請求信息,可是Struts2會採用什麼策略來肯定選擇使用哪個action來處理這個請求呢。
會採用如下策略:
Struts2會掃描struts.xml文件中是否有名爲regist的Action,若是有則使用此Action處理,若是沒有,則會查找與regist匹配的action,這時會找到兩個匹配的信息,即名稱爲」*」的通用Action和名稱爲」*Action」的Action,而後會按照順序選擇第一個找到的Action來處理請求。
因而可知,咱們須要將通用的Action配置放到最後,不然它將處理除了請求與action名絕對相同以外的全部的請求。
方式三:使用Struts2默認約定格式的URL請求< xmlnamespace prefix ="o" ns ="urn:schemas-microsoft-com:office:office" />
咱們可使用下列格式的請求來達到一個Action處理不一樣業務邏輯的效果。
url = 請求前綴+action名!方法名.處理請求後綴的格式。
好比:http://locahost:8888/Demo/LoginAction!login.action這樣一條請求。
表示須要名爲LoginAction的Action的login方法來處理這個請求。
配置默認的Action
<default-action-ref name="defaultAction"></default-action-ref> <action name="defaultAction" class="org.struts2.samples.DefaultAction"> <result name="success">/welcome.jsp</result> </action> |
在Struts2找不到請求與action名絕對相同的Action,也找不到使用通配符可以匹配的Action是就會調用默認的Action來處理請求。也就是說在有通用Action配置的狀況下會先調用通用Action來處理請求。
Action的處理結果
咱們知道Action只是一個處理用戶請求的控制器,他不能也不該該提供處理響應信息。他只提供一個處理結果的邏輯字符串,對應的具體的響應信息則由Struts2查找邏輯視圖名對應的物理資源來產生響應信息。
在struts.xml文件中咱們使用<result>元素來配置處理結果。
處理結果分爲兩種類型:
局部處理結果:將<result>元素做爲<action>元素的子元素來配置。
全局處理結果:將<result>元素做爲<global-results>元素的子元素來配置。如:
<global-results> <result name="success">/${result}.jsp</result> <result name="error">/error.jsp</result> </global-results> |
下面爲<result>元素完整屬性配置格式:
<result name="邏輯視圖名" type="結果類型"> <param name="location">實際視圖資源</param> <param name="parse">true</param> </result> |
其中:
屬性 |
說明 |
name |
邏輯視圖名 |
type |
結果類型,Struts2支持14中類型的結果類型 |
loaction |
指定邏輯視圖名對應的實際視圖資源 |
parse |
指定了是否容許在實際試圖資源名中是否可以使用ONGL表達式。默認值爲true。一般無需修改此屬性的值。 |
一般無需指定parse,因此能夠簡寫爲:
<result name="邏輯視圖名" type="結果類型">實際視圖資源</result> |
Struts2支持處理的14中結果類型:默認dispatcher類型,即jsp資源視圖。
類型 |
說明 |
chain |
Action鏈式處理結果 |
chart |
用於處理JfreeChart類型的視圖資源 |
dispatcher |
用於處理JSP視圖資源 |
freemarker |
用於FreeMarker視圖資源 |
httpheader |
用於控制特殊的Http行爲的視圖資源 |
jasper |
用於JasperReports視圖資源 |
jsf |
用於JSF的結果類型視圖資源 |
redirect |
用於直接跳到其餘URL視圖資源 |
redirect-action |
用於直接跳轉到其餘的Action視圖資源 |
stream |
用於流類型的視圖資源 |
tiles |
用於Tiles類型視圖資源 |
velocity |
用於Velocity類型視圖資源 |
xslt |
用於XML/XSLT類型視圖資源 |
plaintext |
用於顯示某個頁面源碼的視圖資源 |
具體詳細的說明請參考響應的資料瞭解。
使用通配符配置處理結果:
與Action配置信息支持通配符同樣,處理結果也支持通配符。如:
<action name="*Action" class="org.struts2.samples.TwoAction"> <result name="success">/{1}.jsp</result> </action> |
使用ONGL表達式結合請求參數來得到處理結果:
以ONGL表達式,即${屬性名.屬性名.屬性名…}再結合請求中的請求參數共同組合成一個實際的視圖資源。如:
<action name="load" class="org.struts2.samples.TwoAction"> <result name="success" type=」redirect」>/edit.action?name=${user.name}</result> </action> |