struts解析

第1章 struts與java web應用簡介
1.1 java web應用概述
1.2 web組件的三種關聯關係
1.3 muv概述
1.4 struts概述
1.4.1 struts實現mvc的機制
在struts框架中,模型由實現業務邏輯的javabean或ejb組件構成,控制器由

ActionServlet和Action類實現,視圖由一組jsp文件構成。

1.視圖
視圖就是jsp文件。在這些jsp文件中沒有業務邏輯,也沒有模型信息,只有標籤。
通常把struts框架中的ActionForm bean 也劃分到視圖模塊中。struts框架利用ActionForm

bean來進行視圖和控制器之間表單數據的傳遞。struts框架把用戶輸入的表單數據保存在

ActionForm bean中,把它傳遞給控制器,控制器可以對ActionForm bean中的數據進行修改,

jsp文件使用struts標籤讀取修改後的ActionForm bean的信息。重新設置html表單。

2.模型
模型表示應用程序的狀態和業務邏輯。業務邏輯通常由javabean或ejb組件來實現。

3.控制器
控制器由ActionServlet類和Action類來實現。ActionServlet類是struts框架中的核

心組件。ActionServlet繼承了javax.servlet.http.HttpServlet類,它在mvc模型中扮演控制

器的角色。ActionServlet主要負責接收http請求信息,根據配置文件struts-config.xml的配

置信息,把請求轉發給適當的Action對象。如果該Action對象不存在,ActionServlet會先創建

這個Action對象。

Action類負責調用模型的方法,更新模型的狀態,並幫助控制應用程序的流程。對於

小型的應用,Action類本身也可以完成一些實際的業務邏輯。

對於大型應用,Action充當用戶請求和業務邏輯處理之間的適配器(Adaptor),其功能就是將

請求與業務邏輯分開,Action根據用戶請求調用相關的業務邏輯組件。業務邏輯組件由

javabean或者ejb組件來完成,Action類側重與控制應用程序的流程,而不是實現應用程序的邏

輯。通過將業務邏輯放在單獨的java包或ejb中,可以提高應用程序的靈活性和可重用性。

當ActionServlet控制器收到用戶請求後,把請求轉發到一個Action實例。如果這個實

例不存在,控制器會首先創建它,然後調用Action實例的execute()方法。Action的execute

()方法返回一個ActionForward對象,她封裝了把用戶請求再轉發給其他web組件的信息。用

戶定義自己的Action類,即Action基類的子類時,必須覆蓋execute()方法。在Action基類中

該方法返回null。

1.4.2 struts的工作流程

當ActionServlet接收到一個客戶的請求時,將執行如下流程:
1.檢索和用戶請求匹配的ActionMapping實例,如果不存在,就返回用戶請求路徑無效信息。
2.如果ActionForm實例不存在,就創建一個Actionform對象,把客戶提交的表單數據保存到

ActionForm對象中。
3.根據配置信息決定是否需要表單驗證。如果需要驗證,就調用ActionForm的validate()方

法。
4.如果ActionForm的validata()方法返回null或返回一個不包含ActionMessage的

ActionErrors對象,就表示表單驗證成功。
5.ActionServlet根據ActionMapping實例包含的映射信息決定將請求轉發給哪個Action。如果

相應的Action實例不存在,就會創建這個實例,然後調用Action的execute()方法。
6.Action的execute()方法返回一個ActionForward對象,ActionServlet再把客戶請求轉發給

ActionForward對象指向的jsp組件。
7.ActionForward對象指向的jsp組件生成動態網頁,返回給客戶。


第2章 struts應用:helloapp應用

 


第5章 struts控制器組件
struts控制器組件負責接受用戶請求,更新模型,以及選擇合適的視圖組件返回給用

戶。控制器組件有助於將模型層和視圖層分離。

struts控制器組件主要包括:
ActionServlet組件:充當strtus框架的中央處理器
RequestProcessor組件:充當每個子應用模塊的請求處理器
Action組件:負責處理一項具體的業務

strtus框架採用ActionSerblet和RequestProcessor組件進行集中控制,並採用Action組件來

處理單項業務。

5.1 控制器組件的控制機制
struts的控制器組件主要完成以下任務:
a、接收用戶請求
b、根據用戶請求,調用合適的模型組件來執行相應的業務邏輯
c、獲取業務邏輯執行結果
d、根據當前狀態以及業務邏輯執行結果,選擇合適的視圖組件返回給用戶

5.1.1 ActionServlet類
org.apache.struts.action.ActionServlet類是struts框架的核心控制器組件,所有的用戶請

求都先有ActionServlet來處理,然後在由ActionServlet把請求轉發給其他組件。

strtus框架只允許在一個應用中配置一個ActionServlet類,在應用的生命週期中,僅創建

ActionServlet類的一個實例,這個ActionServlet實例可以同時響應多個用戶請求。

1.struts框架初始化過程
servlet容器在啓動時,或者用戶首次請求ActionServlet時加載ActionServlet類。在

這2種情況下,servlet容器都會在ActionServlet被加載後立即執行它的init()方法,這可以

保證當ActionServlet處理用戶請求時已經被初始化。

2.ActionServlet的process()方法
當ActionServlet實例接受到http請求後,在doGet()方法或doPost()方法中都會調用

processs()方法來處理請求。


3.擴展ActionServlet類

5.1.2 RequestProcessor類
對於多應用模塊的struts應用,每個子應用模塊都有各自的RequestProcessor實例。

在ActionServlet的process()方法中,一旦選擇了正確的子應用模塊,就會調用子應用模塊

的Requestprocessor實例的process()方法來處理請求。在ActionServlet調用這個方法時,

會把當前的request和response對象傳給它。

struts框架只允許應用中存在一個ActionServlet類,但是可以存在多個客戶化的

RequestProcessor類,每個子應用模塊都可以擁有單獨的
RequestProcessor類。如果想修改RequestProcessor類的一些默認功能,可以覆蓋

RequestProcessor基類中的相關方法。

1.RequestProcessor類的process()方法。
RequestProcessor類的process()負責實際的預處理請求操作。

2.擴展RequestProcessor類


5.1.3 Action類

Action類是用戶請求和業務邏輯之間的橋樑。每個Action充當客戶的一項業務代理。在

RequestProcessor類預處理請求時,在創建了Action實例後,就調用自身的

processActionPerform()方法,該方法在調用Action類的execute()方法。


Action的execute()方法調用模型的業務方法,完成用戶的業務邏輯,然後根據執行結果把請

求轉發給其他合適的web組件。
1.Action類緩存
爲了確保線程安全,在一個應用的生命週期中,struts框架只會爲每個Action類創建一個

Action實例。所有的客戶請求共享一個Action實例,並且所有請求線程可以同時執行她的

execute()方法。

RequestProcessor類包含一個HashMap,作爲存放所有Action實例的緩存,每個Action實例在緩

存中存放的屬性key爲Action類名。在RequestProcessor類的processActionCreate()方法中,

首先檢查在HashMap中是否存在Action實例,如果存在,就返回這個實例;否則,就創建一個新

的Action實例。創建Action實例的代碼位於同步代碼塊中,以保證只有一個線程創建Action實

例。一旦線程創建了Action實例並把它放到HashMap只,以後所有的線程都會直接使用這個緩存

中的實例。

2.ActionForward類
Action類的execute()方法返回一個ActionForward對象。ActionForward對象代表了web資源

的邏輯抽象,這裏的web資源可以是jsp頁,java servlet或action。從execute()方法中返回

ActionForward對象有2種方法:
a、在execute()方法只動態創建一個ActionForward實例:
return new ActionForward("Failure","/secruity/singnin.jsp",true);
以上ActionForward構造方法的第一個參數代表ActionForward實例的邏輯名,第2個參數指定轉

發路徑,第3個參數指定是否進行重定向。

b、在struts配置文件中配置<forward>元素:

    <action    path      = "/singin"
               type      = "netstore.security.LoginAction"
               name      = "loginForm"
               scope     = "request"
               validate = "true"
               input     = "/security/signin.jsp"
     >
        <forward name="Success" path="/action/home" />
<forward name="Failure" path="/security/signin.jsp" redirect="true"/>
    </action>

配置了<forward>元素後,在sturts框架初始化時,就會創建存放<forward>元素配置信息的

ActionForward對象。

P110


3.創建支持多線程的Action類
在struts應用的生命週期中,只會爲每個Action類創建一個實例,所有的客戶請求共

享這個實例 。因此必須保證在多線程環境中,Action也能正常工作。保證線程安全的重要原則

是在Action類中僅僅使用局部變量,謹慎使用實例變量。

如果在Action的execute()方法中定義了局部變量,對於每個調用execute()方法

的線程,jvm會在每個線程的堆棧中創建局部變量,因此每個線程擁有獨立的局部變量,不會被

其他線程共享。當線程執行完executive()方法是,它的局部變量就會被銷燬。

如果在Action類中定義了實例變量,那麼在Action實例的整個生命週期中,這個實例

變量被所有 的請求線程共享。因此不能在Action類中定義代表特點客戶狀態的實例變量,例如

不能定義購物車實例變量,因爲每個用戶擁有各自不同的購物車。

在Action類中定義的實例變量代表了可以被所有請求線程訪問的共享資源。爲了避免

共享資源的競爭,在必要的情況下,需要採用java同步機制對訪問共享資源的代碼塊進行同步

 

4.Action類的安全
在某些情況下,如果Action類執行的功能非常重要,則只允許特點權限的用戶才能訪問Action

。爲了防止未授權的用戶來訪問Action,可以在配置Action時指定安全角色。

P111

5.2使用內置的struts Action類
最常見的Action類爲:
org.apache.struts.actions.ForwardAction
org.apache.struts.actions.IncludeAction
org.apache.struts.actions.DispatchAction
org.apache.struts.actions.LookupDispatchAction
org.apache.struts.actions.SwitchAction

5.2.1 org.apache.struts.actions.ForwardAction類 P112
如果僅僅需要Action類提供請求轉發功能,則可以使用

org.apache.struts.actions.ForwardAction類。ForwardAction類專門用於轉發請求,不執行

任何其他的業務操作。

ActionServlet把請求轉發給ForwardAction,ForwardAction再把請求轉發給<action>元素中的

parameter屬性指定的web組件。總之,在web組件之間通過ForwardAction類來進行請求轉發,

可以充分利用struts控制器的預處理請求功能。

此外,也可以通過action元素的forward屬性來實現請求轉發,以下代碼能完成同樣功能:
    <action    path      = "/viewsignin"
               forward   = "/security/signin.jsp"
               name      = "loginForm"
               scope     = "request"
               validate = "false"
               input     = "index.jsp"
     >
    </action>


5.2.2 org.apache.struts.actions.IncludeAction類 p114

5.2.3 org.apache.struts.actions.DispatchAction類
通常,在一個Action類中只能完成一種業務操作,如果希望在同一個Action類中完成一組相關

的業務操作,可以使用DispatchAction類。

創建一個擴展DispatchAction類的子類,不必覆蓋execute()方法,而是創建一些實現實際業

務操作的方法這些業務方法都應該和execute()方法具有同樣的方法簽名,即他們的參數和返

回類型的哦應該相同,此外也應該聲明拋出Exception。


5.2.4 org.apache.struts.actions.LookupDispatchAction類
LookupDispatchAction類是DispatchAction的子類,在LookupDispatchAction類中也

可以定義多個業務方法。通常LookupDispatchAction主要應用於在一個表單中有多個提交按鈕

,而這些按鈕又有一個共同的名字的場合,這些按鈕的名字和具體的ActionMapping的

parameter屬性值相對應。

5.2.5 org.apache.struts.actions.SwitchAction類
SwitchAction類用於子應用模塊之間的切換。

5.3 利用Token解決重複提交 p121


5.4 實用類

 

 

第6章 struts 模型組件

6.1 模型在mvc中的地位
struts應用的各個層次直接的依賴關係:
從上倒下:視圖層 - 控制層 - 模型層 - 持久層 - 網絡層
從上倒下依賴關係加強;從下到上依賴關係減弱

6.2 模型的概念和類型
6.2.1 概念模型
在簡歷模型之前,首先要對問題進行詳細分析,確定用例,接下來就可以根據用例來

創建概念模型。概念模型用例模擬問題域中的真實實體。概念模型描述了每個實體的概念和屬

性,以及實體之間的關係。但在這個階段並不描述實體的行爲。
創建概念模型的目的是幫助更好地理解問題域,識別系統中的實體,這些實體在設計

階段很有可能變爲類。

6.2.2 設計模型
概念模型是在軟件分析階段創建的,她幫助開發人員對應用的需求獲得清晰明確的理

解。在軟件設計階段,需要在概念模型的基礎上創建設計模型。可以用uml類框圖,活動圖以及

狀態圖來描述設計模型。

1. 關聯(Associaion)
關聯是類之間的引用關係。例如訂單類對象OrderBO需要引用CustomerBO對象,來表明這個訂單

是由那個客戶發出的。如果類A引用類B,那麼被應用的類B將被定義爲類A的屬性。

2. 依賴(Dependency)
依賴是是類之間的訪問關係。如果類A引用類B的屬性或方法,那麼可以說類A依賴類B。與關聯

關係不同的是,無需把類B定義爲類A的屬性。

3. 累積(Aggregation)
累積是指整體與個體之間的關係,可以把積累看作一種強關聯關係。例如:購物車

ShoppingCart和購物條目ShoppingCartItem之間就是積累關係。一個購物車包括多個購物條目

。如果類A和類B之間存在累積關係,那麼在類A中會定義一個集合屬性,來存放類B對象。例如

,在ShoppingCart中定義了addItem()方法和removeItem()方法,用例向List中加入或刪除

ShoppingCartItem對象。

4.一般化(Generalization)
一般化指類之間的繼承關係。


6.3 業務對象(business object:BO)
BO是對真實世界的實體的軟件抽象。她可以代表業務領域中的人,地點,事物或概念
BO包括狀態和行爲。

6.3.1業務對象的特徵和類型
如果一個類可以作爲業務對象,它應具有以下特徵:
a、包含狀態和行爲
b、代表業務領域的人,地點,事物,概念
c、可以重用

bo可以分爲3種類型:
a、實體業務對象
實體業務對象可以代表人,地點,事物或概念。通常把業務領域中的名詞,例如:客

戶,訂單,商品等作爲實體業務對象。

b、過程業務對象
過程業務對象代表應用中的業務過程或流程,他們通常依賴與實體業務對象。可以把

業務領域中的動詞,例如:客戶發出訂單,登入應用等作爲過程業務對象。

c、事件業務對象
事件業務對象代表應用中的一些事件(例如異常,警告,超時)。這些事件通常由系

統中的某種行爲觸發。

6.3.2業務對象的重要性
在應用中使用業務對象有許多好處,最重要的一點就是業務對象提供了通用的術語和

概念,不管是技術人員還是非技術人員都可以共享並理解他們。
此外,業務對象可以隱藏實現細節,對外只暴露接口。


6.4 業務對象的持久化

6.4.1對業務對象進行持久化的作用

6.4.2數據訪問對象(DAO)設計模式
對象-關係的映射(object-Relation Mapping,簡稱orm)是一種耗時的工作,圍繞對象-關係

和持久化數據的訪問,在軟件領域中發展起來了一種數據訪問對象(Data Access Object,簡

稱DAO)設計模式。

DAO模式提供了訪問關係型數據庫系統所需要的所有操作的接口,其中包括創建數據庫,定義表

,字段,索引,簡歷表間的關係,更新和查詢數據庫等。

DAO模式將底層數據庫訪問操作與高層業務邏輯分離開,對上次提供面向對象的數據訪問接口。


ORM框架是一種持久化框架。DAO是用於實現持久化框架的一種設計模式。

 

 


第7章 struts視圖組件

7.1視圖概述
視圖是模型的外在表現形式,用戶通過視圖來了解模型的狀態。
7.2 在視圖中使用javabean
7.2.1 DTO數據傳輸對象
DTO:Data Transfer Object。DTO用於在不同層之間傳遞數據。例如:可以在模型層與視圖層

之間通過DTO傳遞數據。
沒有把模型層的業務對象直接傳遞到視圖層,而是通過DTO來傳輸數據,這樣做有2個

好處:
a、減少傳輸數據的冗餘,提供傳輸效率。
b、有助於實現各個層之間的獨立,使每個層分工明確。

7.2.2 struts框架提供的DTO:ActionForm Bean
ActionForm bean是struts框架提供的DTO,用於在視圖層和控制層之間傳遞html表單

數據。控制層可以從ActionForm bean中讀取用戶輸入的表單數據,也可以把來自模型層的數據

存放到ActionForm bean中,然後把它返回給視圖。

7.3使用ActionForm

7.3.1ActionForm的生命週期

控制器接受到請求 - 從request或session範圍中取出ActionForm實例,如果該實例不存在,就

自動創建一個新的實例 - 調用ActionForm的reset()方法 - 把ActionForm實例保存在

request或session範圍中 - 把用戶輸入的表單數據組裝到ActioinForm中 - 如果<action>

的validate屬性爲true,則調用ActionForm的validate()方法   - "存在驗證錯誤" - 把請求

轉發給<action>的input屬性指定的web組件,ActoinForm實例依然保存在request或session範

圍內 - "無驗證錯誤" - 調用Action的execute()方法,把ActionForm實例傳遞給execute()方

法 - 把請求轉發給其他web組件,ActionForm實例依然保存在request或session範圍內


ActionForm中的validate()方法:
如果struts的配置文件滿足以下2個條件,struts控制器就會調用ActionForm的validate()方法


1.爲ActionForm配置了Action映射,即<form-bean>元素的name屬性和<action>元素的name屬性

匹配
2.<action>元素的validate屬性爲true


在ActionForm基類中定義的validate()方法直接返回null,如果創建了擴展ActionForm基類的

子類,那麼應該在子類中覆蓋validate()方法。

validate()方法返回ActionErrors(或者ActionMessages)對象,如果返回的對象爲null,或

者不包含任何ActionErrors(或者ActionMessages)對象,就表示沒有錯誤,數據驗證通過。

如果ActionErrors中包含ActionMessage對象,就表示發生了驗證錯誤。

validate()方法主要負責檢查數據的格式和語法,而不負責檢查數據是否符合業務邏輯。例如

:html表單的文本域只能處理字符串類型的數據,所以在ActionForm中可以把年齡,數量等定

義爲字符串類型屬性,如何在validate()方法中進行驗證,判斷是否可以把用戶輸入的年齡,

數量轉換爲有效的數字。


ActionForm中的reset()方法:
不管Actionform存在於那個範圍內,對於每個請求,控制器都會先調用ActionForm的reset()方

法,然後在把用戶輸入的表單數據組裝到ActionForm中。reset()方法用於恢復ActionForm的

屬性的默認值。

如果ActionForm在request範圍內,那麼對於每個新的請求都會創建新的ActionForm實例。當新

的實例創建後,如果它的屬性已經被初始化爲默認值,那麼接着在在reset()方法中把屬性設

置爲默認值不是很有必要。因次在這種情況下,可以讓reset()方法爲空。
對於session範圍內的ActionForm,同一個ActionForm實例會被多個請求共享,reset()方法

在這種情況下極爲有用。

7.3.4訪問ActionForm
ActionForm可以被jsp,struts標籤,Action和其他web組件訪問。訪問ActionForm大致有以下

一些方法:
1.使用strtus HTML 標籤庫
<html:form>標籤能夠和ActionForm交互,讀取ActionForm的屬性值把他們賦值給表單

中對應的字段。
2.從request或session範圍內取出ActionForm實例
strutrs框架把ActionForm實例保存在HttpServletRequest或HttpSession中,保存時

採用的屬性Key爲<form-bean>元素的name屬性。因此如果ActionForm在request範圍內,則可以

調用HttpServletRequest的getAttribue()方法讀取ActionForm實例。例如:
LoginForm loginForm = (LoginForm)request.getAttribute("loginForm");
如果ActionForm在session範圍內,則可以調用HttpSession的getAttribue()方法讀

取ActionForm實例。例如:
LoginForm loginForm = (LoginForm)session.getAttribute("loginForm");
3.在Action類的execute()方法中直接訪問ActionForm
如果配置了ActionForm和Action的映射,struts框架就會把ActionForm作爲參數傳遞

給Action的execute()方法,因此在Action類的execute()方法中可以讀取或設置

ActionForm屬性。
public ActionForward execute(ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response) throws Exception{
String mail = ((LoginForm)form).getEmail();
String pwd = ((LoginForm)form).getPassword();
}


7.3.5處理表單跨頁


7.4使用動態ActionForm

ActionForm的唯一缺點就是對於大型的struts應用,必須以編程的方式創建大量的ActionForm

類,如果html表單的字段發生變化,就必須修改並重新編譯相關的ActionForm類。

struts1.1對此做了改進,引入了動態ActionForm類的概念。struts框架的DynaActionForm類及

其子類實現了動態ActionForm,DynaActionForm類是ActionForm的子類。
7.4.1配置動態ActionForm


7.4.2動態的ActionForm的reset()方法
DynaActionForm基類提供了initialize()方法,它把表單的所有屬性恢復爲默認值。表單屬

性默認值由<fomr-bean><form-property>子元素的initial屬性決定。如果沒有設置initial屬

性,則表單屬性的默認值由其java類型來自動決定,例如對象類型的默認值爲null,整數類型

的默認值爲0,boolean類型的默認值爲false。
DynaActionForm基類的reset()方法不執行任何操作。

如果希望struts框架在每次把表單數據組裝到動態ActionForm中之前,先把所有的屬性恢復爲

默認值,可以定義一個擴展DynaActionForm類的子類,然後覆蓋reset()方法,在reset()

方法中只要調用initalize()方法即可。

7.4.3訪問動態ActionForm
Action類和jsp都可以訪問動態ActionForm,使用方法與標準ActionForm大致相同,只有一點小

差別。
如果使用標準的ActionForm對象,在標準ActionForm中針對每個屬性都提供了get、set方法,

來讀取和設置屬性,例如對email屬性,應該提供了getEmail()和setEmail()方法。

而DynaActionForm把所有的屬性保存在一個Map類對象中,並提供了下面勇於訪問所有屬性的通

用方法:
public Object get(Sring name)
public void set(String name,String value)

get(String name)方法根據指定的屬性名返回屬性值;
set(String name,String value)方法用於爲定的屬性賦值。
//get email
String email = (String)form.get("email");
//set email
form.set("email","[email protected]");


7.4.4動態ActionForm的表單驗證
DynaActionForm基類的validate()方法沒有提供任何默認的驗證行爲。可以定義擴

展DynaActionForm的子類,然後覆蓋validate()方法,但是以編程的方式來驗證動態

ActionForm違背了struts框架提供動態ActionForm的初衷,即以配置來替代編程。

幸運的是,可以採用另一種驗證機制,即validator框架來完成驗證。validator框架允許採用

特定的配置文件來爲動態ActionForm配置驗證規則。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章