struts2重要知識點總結(2)
Action的配置
的配置
通過上面的示例可以看出,Action需要在struts.xml中配置才可以使用,而且Action應該配置成為元素的子元素,那麼元素的功能是什麼呢?
元素可以把邏輯上相關的一組Action、Result、Intercepter等元素封裝起來,形成一個獨立的模組,package可以繼承其他的package,也可以作為父包被其他的package繼承,比如前面示例中配置的“”,helloworld這個包就繼承了struts-default這個包。
元素有如下屬性:
name:包的名稱。必須配置
extends:要繼承的包,後面配置的是被繼承的包的名稱。可選
namespace:包的名稱空間。可選
abstract:定義包為抽象的,也就是不能包含Action的定義。可選
上面的屬性中name和extends在前面已經示例過了,接下來看看另外兩個屬性的應用。
1:namespace
namespace配置的是包的名稱空間,同一個名稱空間裡面不能有同名的Action,當然不同的名稱空間裡面是可以有同名的Action的。類似於Java的包的功能,namespace可以有效的防止action重名的衝突,因為配置了namespace後,在訪問action的時候就需要新增namespace來作為action的字首。
如果不配置namespace,表示是預設的namespace,那麼訪問的時候不需要新增namespace字首。比如前面HelloWorld的示例,struts.xml的配置如下:
1.
namespace=" /ch10" >
<!—定義全域性返回型別 -->
<global-results>
<result name="global-result">/welcome.jsp</result>
</global-results>
<action name="Register" class="ch10.Register">
<!—定義區域性返回型別 -->
<result name="success" type="dispatcher">/ch10/success.jsp</result >
<result name="input">/ch10/register.jsp</result>
</action>
</package>
name型別:
chain:Action鏈式處理的result型別,將兩個連續執行的Action串聯,通過前一個Action的getter方法與後一個Action的對應setter方法完成Action的傳遞。
chart:用於整合JfreeChart的result型別。
dispatcher:預設型別,用於整合JSP的result型別。相當於Servlet中的請求轉發,返回的JSP頁面並不顯示其真正的URL,仍是Action的URL。
freemarker:用於整合FreeMarker的result型別。
httpheader:用於處理特殊HTTP行為的result型別。
jasper:用於整合JasperReport的result型別。
jsf: 用於整合JSF型別。
redirect:用於重定向的result型別。重定向到另一個JSP頁面,並且會顯示該頁面的真正URL。
redirectAction/redirect-action:用於重定向到其他Action的result型別。
stream:用於向瀏覽器返回一個Inputstream,一般用於檔案下載。
tites:用於整合Tiles的result型別。
velocity:用於整合Velocity的result型別。
xslt:用於整合XML/XSLT的result型別,用於Action執行完畢後屬性資訊的轉換。
plaintext:用於顯示頁面的原始程式碼的result型別。
說明:以上是Struts2框架的內建的result型別,都在struts-default.xml中定義的,系統會自動載入該result型別。另外一種result型別是採用外掛的方式來支援的。
type屬性
dispatcher型別是Struts2框架預設的結果型別,相當於是轉發。所以它具備轉發的特徵,比如,dispatcher的目標只能是同一個瀏覽器中的url不會改變,呼叫者和被呼叫者之間共享相同的內建物件(request和response物件)。其中如果有location,該location只能是頁面,不能是action,如果需要是action,則可以用chain來解決此問題。
“dispatcher”的ResultType,在struts-default.xml裡的配置如下:
<result-type name="dispatcher"
class="org.apache.struts2.dispatcher.ServletDispatcherResult"
default="true"/>
通過配置可以看出,它對應的實現類是ServletDispatcherResult。
如果採用JSP作為檢視的實現技術,那麼這個ResultType是最常用的。在這個ResultType的實現中,呼叫了javax.servlet.RequestDispatcher類的forward方法,也就是說它相當於是對RequestDispatcher的一個再包裝。
那麼在Servlet中使用RequestDispatcher來進行頁面跳轉的特性,也就自然被“dispatcher”這個ResultType繼承下來了。那麼Servlet中的RequestDispatcher,到底有什麼特性呢?
那就是通過RequestDispatcher來進行頁面跳轉,將會保持是同一個請求物件。這有什麼好處呢?由於是同一個物件,那就意味著有同樣的資料,而請求物件裡面資料眾多,在Servlet的request物件裡面,典型有如下資料:
引數區(parameter),就是使用者在頁面上填寫並提交的資料
Head區,由瀏覽器在發出請求的時候,自動加入到請求包的資料
屬性區(Attribute),由開發人員儲存在屬性區的值,通常是通過request.setAttribute方法、request.getAttribute方法來進行訪問
Cookie區,由瀏覽器在發出請求的時候,自動把相關的Cookie資料通過request傳遞到服務端
對於dispatcher的使用範圍,除了可以配置jsp外,還可以配置其他的web資源,比如其他的Servlet等。
如果在web.xml中有如下配置:
1.
2. login
3. servlet.LoginServlet
4.
5.
6. login
7. /login
8.
那麼在struts.xml中可以如下配置:
/login
但是請注意,如果這個web資源是另一個Action的話,不能這麼配置,需要使用Struts2的另一種名稱為“chain”的ResultType。
使用“dispatcher”的ResultType,不能訪問其他web應用中的web資源。當然,這個特性是由javax.servlet.RequestDispatcher類的forward方法決定的。
redirect相當於是重定向,因此,不僅可以重定向同一個Web應用的其他JSP頁面,還可以定向到其他外部資源。url也是更改為重定向之後的頁面地址。呼叫者和被呼叫者之間不共享內建物件。如:
/WEB-INF/page/hello.jsp?msg=
redirectActin/redirect-action用於重定向到另一個Action。如:
helloworld
/test
chain用於串聯兩個連續執行的Action,如:
1. package action;
2.
3. import com.opensymphony.xwork2.ActionInvocation;
4. import com.opensymphony.xwork2.interceptor.PreResultListener;
5.
6. public class MyPreResult implements PreResultListener{
7. public void beforeResult(ActionInvocation actionInvocation, String result) {
8. System.out.println("現在處理Result執行前的功能,result="+result);
9. }
10. }
這個類中出現了ActionInvocation物件,這個物件封裝了Action執行所需要的東西,包括資料、代理物件等,甚至可以通過它來執行Action。
然後在Action的execute方法裡面,註冊這個監聽器物件,示例如下:
1. package cn.javass.action.action;
2. import com.opensymphony.xwork2.ActionContext;
3. import com.opensymphony.xwork2.ActionSupport;
4. import com.opensymphony.xwork2.interceptor.PreResultListener;
5. public class HelloWorldAction extends ActionSupport {
6. private String account;
7. private String password;
8. private String submitFlag;
9.
10. public String execute() throws Exception {
11. this.businessExecute();
12. PreResultListener pr = new MyPreResult();
13. ActionContext.getContext().getActionInvocation().addPreResultListener(pr);
14. return this.SUCCESS;
15. }
16. /**
17. * 示例方法,表示可以執行業務邏輯處理的方法,
18. */
19. public void businessExecute(){
20. System.out.println("使用者輸入的引數為==="+"account="+account+",password="+password+",submitFlag="+submitFlag);
21. }
22. //屬性對應的getter/setter方法,省略了
23. }
struts.xml沒有什麼變化,就是最簡單的配置,如下:
1. <?xml version="1.0" encoding="UTF-8" ?>
2. <!DOCTYPE struts PUBLIC
3. "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
4. "http://struts.apache.org/dtds/struts-2.0.dtd">
5.
6. <struts>
7. <constant name="struts.devMode" value="true" />
8. <constant name="struts.locale" value="zh_CN"/>
9. <constant name="struts.i18n.encoding" value="utf-8"/>
10.
11. <package name="helloworld" extends="struts-default">
12. <action name="helloworldAction" class="action.HelloWorldAction">
13. <result>/s2impl/welcome.jsp</result>
14. </action>
15. </package>
16. </struts>
為了看出PreResult確實是在Result之前執行的,可以在welcome.jsp裡面簡單的輸出一句話,如下所示:
1. <%@ page language="java" contentType="text/html; charset=utf-8"
2. pageEncoding="utf-8"%>
3. <html>
4. <head>
5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
6. <title>Insert title here</title>
7. </head>
8. <body>
9. <%
10. System.out.println("現在輸出Result頁面");
11. %>
12. </body>
13. </html>
備註:有些知識點是看別人的總結,但是不知具體是出自誰之手,再次不能表明出處了,還望原作者海涵,如有需要,請告之!!