struts2呼叫方法及返回值
1. 方法呼叫
1. 預設方法
2. 自定義方法
3. 動態方法
一個Action類可以有多個業務邏輯方法,但是隻需要配置一個Action標籤,不需要method屬性,在呼叫時指出Action名和業務邏輯方法。使用動態方法呼叫步驟如下:
-
struts.xml 開啟動態方法呼叫
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
-
編寫Action
-
註冊Action
<!-- 2.5 版本後需要配置此屬性才能夠使用動態方法和萬用字元 --> <global-allowed-methods>regex:.*</global-allowed-methods> <action name="userinfoAction" class="com.javaee.struts2.action.UserinfoAction"> <result>/index.jsp</result> </action>
==注意== 2.5 版本後為了安全動態方法和萬用字元在使用的時候需要新增如下程式碼:
<global-allowed-methods>regex:.*</global-allowed-methods>
禁用動態方法
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
動態方法特點:
-
一個Action類中有多個業務方法
-
一個Action類只需要配置一個<action>標籤
-
相比使用method屬性,Action的配置數量減少
-
請求時指明Action和業務方法
==總結==:動態方法核心就是去掉Action中method屬性,在URL請求呼叫的時候通過!攜帶方法名稱
4. 萬用字元
result 預設是轉發
redirect 重定向URL 或Action
redirectAction 重定向到Action
<action name="user_*" class="com.javaee.struts2.action.UserinfoAction" method="{1}">
<result name="success">/index.jsp</result>
</action>
<action name="*_*" class="com.javaee.struts2.action.{1}Action" method="{2}">
<result name="success">/index.jsp</result>
</action>
Action 匹配順序
-
優先使用完全匹配
-
當完全匹配匹配上,在使用萬用字元匹配
-
當多個萬用字元都匹配上時,優先使用寫在前面的action
預設Action配置
當訪問Action 找不到的時候會訪問預設Action
<default-action-ref name="index" />
<action name="index">
<result>/index.jsp</result>
</action>
2. 返回值
2.1 name 屬性
==result== : 每個Action 返回一個字串,Struts2根據這個值來決定響應什麼結果。 ==name屬性==:result的邏輯名稱。和Action裡返回值匹配。預設是success ==值==:指定對應的實際資源位置
2.2 type 屬性
type 屬性指定result的型別,不同型別的result 代表的不同的結果輸出 type預設是是轉發(dispatcher)
type 常見取值介紹
-
redirect 請求重定向指定的URL或者Action
-
redirectAction 請求重定向到指定的Action
-
chain Action鏈式處理,將請求轉發(forward)到指定的Action
-
json 實現Ajax時返回JSON物件
2.3 struts2 中 dispatcher、redirect和chain型別的區別
-
dispatcher:用於頁面轉發,頁面跳轉過程一直是同一個執行緒,Action中的資料一直儲存在。
-
redirect:可用於返回一個頁面、一個action、連結到一個網址。
-
缺點:redirect把一個http返回碼(SUCCESS)以及返回的頁面位置一起重新發給web伺服器,容納後由web伺服器產生一個新的HTTP請求,就會產生一個新的執行緒,儲存在原來Action執行的執行緒中的資料就無法訪問。所以,result需要包含Action的資料,那麼redirect不是一個可行的辦法。因為新的HTTP請求時在Servlet容器的新的執行緒中處理的,ActionContext中的所有狀態都不會存在。
-
chain:功能與redirect的action轉發類似,不過與redirectaction轉發功能不同的是它可以將Action中的資料一直儲存在同一個HTTP請求中。
==1.跳轉方式==dispatcher和chain是伺服器端跳轉,所以客戶端只發起一次請求,產生一個action;redirect和redirectAction是客戶端跳轉,所以客戶端發起兩次請求。
==2.跳轉內==容dispatcher和redirect跳轉的是views(一般是jsp頁面);chain和redirectAction跳轉的是一個action。
2.3 全域性返回結果
<!-- 全域性返回配置,必須放在action的前面 -->
<!-- action中的result優先於全域性result,當全域性的result和Action中的result中都沒有配置的時候就去父類中查詢,如果父類中沒有時就回報錯 -->
<global-results>
<result name="error">/error.jsp</result>
</global-results>
==全域性結果總結==
-
使用<result > 來配置,只不過不是在<action>中配置,而是在<global-result>中巢狀
-
當所有Action需要共享某個結果時,可以定義為全域性結果、
-
全域性結果的影響範圍整個包含的所有Action,如果不是對所有Action都有效的結果,不要定義在全域性返回結果中
==Result搜尋順序==
-
首先找自己的<action>元素內的<result>元素是否有匹配的。如果有就執行這個result,沒有執行下一步
-
其次找自己<action>所在的包的全域性result是否有匹配的,如果有就執行這個result,沒有執行下一步
-
遞迴尋找自己的包的父包、祖包中的全域性result是否有匹配的,如果有就執行這個result,沒有執行下一步
-
最後都沒找到就丟擲Exception異常
2.4 動態返回結果
private HouseUser user;
//記錄下一個跳轉的Action是誰
private String nextDispose;
//userACtion訪問的方法
public String login() {
if (user.getUsername().equals("common")&& user.getPassword().equals("common")) {
nextDispose = "common";// 下一個result中name的別名
return SUCCESS;
} else if (user.getUsername().equals("admin")&& user.getPassword().equals("admin")) {
nextDispose = "admin";
return SUCCESS;
} else {
return INPUT;
}
}
//省略getXXX()/setXXX()
<!-- 動態結果 -->
<package name="user" namespace="/user" extends="struts-default">
<action name="login" class="com.javaee.struts2.action.UserAction" method="login">
<result name="success" type="redirectActioin">${nextDispose}</result>
<result name="input">/login.jsp</result>
</action>
</package>
2. 返回JSON資料
-
採用傳統JSON輸出方法沒有返回值,通過Struts2呼叫Servlet 底層API獲得Response物件(HttpServletResponse response=ServletActionContext.getResponse();)進行JSON資料輸出
struts.xml配置
<package name="default" extends="struts-default" namespace="/">
<action name="testJsonAction" class="com.javaee.struts2.action.TestJsonAction" method="doAction">
</action>
</package>
==注意==:action 沒有result,且方法也是沒有返回值
-
使用Struts2 方式
-
新增struts2-json-plugin.jar
-
package 必須繼承json-default
-
result 返回值 type型別修改為json
<result type="json">
<!-- 這裡指定將被Struts2序列化的屬性,該屬性在action中必須有對應的getter方法 -->
<!-- 預設將會序列所有有返回值的getter方法的值,而無論該方法是否有對應屬性 -->
<param name="root">dataMap</param>
<!-- 指定是否序列化空的屬性 -->
<param name="excludeNullProperties">true</param>
<!-- 這裡指定將序列化dataMap中的那些屬性 -->
<param name="includeProperties">userList.*</param>
<!-- 取消瀏覽器快取-->
<param name="noCache">true</param>
<!-- 設定伺服器響應型別-->
<param name="contentType">application/json</param>
<!-- 這裡指定將要從dataMap中排除那些屬性,這些排除的屬性將不被序列化,一半不與上邊的引數配置同時出現 -->
<param name="excludeProperties">SUCCESS</param>
</result>
==result==總結
-
name 屬性:result邏輯名稱,和Action裡返回值匹配,預設"success"
-
type 屬性:結果型別,預設dispatcher
-
全域性結果:通過<global-results> 配置,對包內所有Action都有效的結果
-
動態結果:執行結果在配置時並不知道在執行時刻才能夠確定