1. 程式人生 > >struts2重要知識點總結(2)

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=messagetrue使{message},在程式執行時將被替換成具體的值,該值由Action類的message屬性決定。如果Action中message屬性沒有定義,那麼表示式${message}的值為null。
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>

備註:有些知識點是看別人的總結,但是不知具體是出自誰之手,再次不能表明出處了,還望原作者海涵,如有需要,請告之!!