<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    空間站

    北極心空

      BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
      15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks

    Struts 控制器組件負(fù)責(zé)接受用戶請(qǐng)求、更新模型,以及選擇合適的視圖組件返回給用戶。控制器組件有助于將模型層和視圖層分離,有了這種分離,就可以在同一個(gè)模型的基礎(chǔ)上得心應(yīng)手地開發(fā)多種類型的視圖。 Struts 控制器組建主要包括:

    ?

    · ActionServlet 組件:充當(dāng) Struts 框架的中央控制器。

    · RequestProcessor 組件:充當(dāng)每個(gè)子應(yīng)用模塊的請(qǐng)求處理器。

    · Action 組件:負(fù)責(zé)處理一項(xiàng)具體的業(yè)務(wù)。

    ?

    Struts 框架采用控制器組件來(lái)預(yù)處理所有的客戶請(qǐng)求,這種集中控制方式可以滿足 MVC 設(shè)計(jì)模式的兩大需求:

    ?

    ·首先,控制器在用戶輸入數(shù)據(jù)和模型之間充當(dāng)媒介 / 翻譯者的角色,提供一些通用功能,如安全、登入和其他針對(duì)具體用戶請(qǐng)求的重要服務(wù),當(dāng)系統(tǒng)的這些通用功能出現(xiàn)需求變更時(shí),部需要修改整個(gè)應(yīng)用,只需要修改局部的控制器組件即可。

    ·其次,由于所有的請(qǐng)求都經(jīng)過(guò)控制器過(guò)濾,因此可以降低視圖組件之間,以及視圖組件和模型組件之間的相互依賴關(guān)系,提高每個(gè)組件的相對(duì)獨(dú)立性。由控制器組件來(lái)決定把合適的視圖組件返回給用用戶,這可以減少視圖組件之間直接的,錯(cuò)綜復(fù)雜的連接關(guān)系,使應(yīng)用更加靈活,便于維護(hù)。

    ?

    Struts 框架采用 ActionServlet RequestProcessor 組件進(jìn)行集中控制,并采用 Action 組件來(lái)處理單項(xiàng)業(yè)務(wù)。

    ?

    ?

    控制器組件的控制機(jī)制

    ?

    Struts 的控制器組件主要完成以下任務(wù):

    ·接受用戶請(qǐng)求

    ·根據(jù)用戶請(qǐng)求,調(diào)用合適的模型組件來(lái)執(zhí)行相應(yīng)的業(yè)務(wù)邏輯。

    ·獲取業(yè)務(wù)邏輯執(zhí)行結(jié)果。

    ·根據(jù)當(dāng)前狀態(tài)以及業(yè)務(wù)邏輯執(zhí)行結(jié)果,選擇合適的視圖組件返回給用戶。

    ?

    1 Action

    ?

    ?org.apache.struts.action.ActionServlet 類是 Struts 框架的核心控制器組件,所有的用戶請(qǐng)求都先有 ActionServlet 來(lái)處理,然后再由 ActionServlet 把請(qǐng)求轉(zhuǎn)發(fā)給其他組件。 Struts 框架只允許在一個(gè)應(yīng)用中配置一個(gè) ActionServlet 類,在應(yīng)用的生命周期中,僅創(chuàng)建 ActionServlet 類的一個(gè)實(shí)例,這個(gè) ActionServlet 實(shí)例可以同時(shí)響應(yīng)多個(gè)用戶請(qǐng)求。

    ?

    <!--[if !supportLists]-->(a)???<!--[endif]-->Struts框架初始化過(guò)程

    <!--[if !supportLists]-->(1)???<!--[endif]-->調(diào)用initInternal()方法,初始化Struts框架內(nèi)在的消息資源,如與系統(tǒng)日志相關(guān)的同志、警告和錯(cuò)誤消息。

    <!--[if !supportLists]-->(2)???<!--[endif]-->調(diào)用initOther()方法,從web.xml文件中加載ActionServlet的初始化參數(shù),如config參數(shù)。

    <!--[if !supportLists]-->(3)???<!--[endif]-->調(diào)用initServlet()方法,從web.xml文件中加載ActionServletURL映射信息。此外還會(huì)注冊(cè)web.xmlStruts配置文件所使用的DTD文件,這些DTD文件用來(lái)驗(yàn)證web.xmlStruts配置文件的語(yǔ)法。

    <!--[if !supportLists]-->(4)???<!--[endif]-->調(diào)用initModuleConfig()方法,加載并解析子應(yīng)用模塊的Struts配置文件;創(chuàng)建ModuleConfig對(duì)象,把它存儲(chǔ)在ServletContext中。

    <!--[if !supportLists]-->(5)???<!--[endif]-->調(diào)用initModuleMessageResources()方法,加載并初始化默認(rèn)子應(yīng)用模塊的消息資源:創(chuàng)建MessageResources對(duì)象,把它存儲(chǔ)在ServletContext中。

    <!--[if !supportLists]-->(6)???<!--[endif]-->調(diào)用initModuleDataSources()方法,加載并初始化默認(rèn)子應(yīng)用模塊的數(shù)據(jù)源。如果在Struts配置文件中沒有定義<data-sources>元素,就忽略這一流程。

    <!--[if !supportLists]-->(7)???<!--[endif]-->調(diào)用InitModulePlugins()方法,加載并初始化默認(rèn)子應(yīng)用模塊的所有插件。

    <!--[if !supportLists]-->(8)???<!--[endif]-->當(dāng)默認(rèn)子應(yīng)用模塊被成功地初始化后,如果還包括其他子應(yīng)用模塊,將重復(fù)流程(4)(7),分別對(duì)其他子應(yīng)用模塊進(jìn)行初始化。

    ?

    <!--[if !supportLists]-->(b)???<!--[endif]-->ActionServletprocess()方法

    當(dāng) ActionServlet 實(shí)例接受到 HTTP 請(qǐng)求之后,在 doGet() doPost() 方法都會(huì)調(diào)用 process() 方法來(lái)處理請(qǐng)求。一下是 ActionServlet process() 方法的源代碼:

    ?

    protected voidprocess (HttpServletRequest request, HttpServletResponse response)

    throwIOException, ServletException {

    ?

    ModuleUtils.getInstance().selectModule(request,getServletContext());

    getRequestProcessor(getModuleConfig(request)).process(request,response);

    }

    ?

    process() 方法中,首先調(diào)用 org.apache.struts.util.ModuleUtils 類的 selectModule() 方法,這個(gè)方法選擇負(fù)責(zé)處理當(dāng)前請(qǐng)求的子應(yīng)用模塊,然后把與子應(yīng)用模塊相關(guān)的 ModuleConfig MessageResources 對(duì)象存儲(chǔ)倒 request 范圍中,這使得框架的其余組件可以方便地從 request 范圍中讀取這些對(duì)象,從而獲取應(yīng)用配置信息和消息資源。

    process() 方法的第二步操作為獲得 RequestProcessor 類的實(shí)例,然后調(diào)用 RequestProcessor 類的 process() 方法,來(lái)完成十幾的預(yù)處理請(qǐng)求操作。

    ?

    ?

    <!--[if !supportLists]-->(c)???<!--[endif]-->擴(kuò)展ActionServlet

    Sturts 1.1 之前的版本中, ActionServlet 類本身包含了很多處理請(qǐng)求的代碼。從 Struts 1.1 開始,多數(shù)功能被移到 org.apache.struts.action.RequestProcessor 類中,以便減輕 ActionServlet 類的控制負(fù)擔(dān)。

    ?

    盡管新版本的 Struts 框架允許在應(yīng)用中創(chuàng)建礦展 ActionServlet 類的子類,但是這在多數(shù)情況下沒有必要,因?yàn)榭刂破鞯亩鄶?shù)控制功能位于 RequestProcessor 類中。

    ?

    如果實(shí)際應(yīng)用確實(shí)需要?jiǎng)?chuàng)建自己的 ActionServlet 類,則可以創(chuàng)建一個(gè) ActionServlet 的子類,然后在 web.xml 文件中配置這個(gè)客戶化 ActionServlet 類。

    ?

    如果覆蓋了 init() 方法,應(yīng)該確保首先調(diào)用 super.init() ,它保證 ActionServlet 的默認(rèn)初始化操作被執(zhí)行。除了覆蓋 init() 方法外,事實(shí)上,還可以根據(jù)十幾需要覆蓋 ActionServlet 的任何其他方法。

    ?

    ?

    2 RequestProcessor

    ?

    ? 對(duì)于多應(yīng)用模塊的 Struts 應(yīng)用,每個(gè)子應(yīng)用模塊都有各自的 RequestProcessor 實(shí)例。在 ActionServlet process() 方法中,一旦選擇了正確的子應(yīng)用模塊,就會(huì)調(diào)用子應(yīng)用模塊的 RequestProcessor 實(shí)例的 process() 方法來(lái)處理請(qǐng)求。在 ActionServlet 調(diào)用這個(gè)方法時(shí),會(huì)把當(dāng)前的 request response 對(duì)象傳給它。

    Struts 框架只允許應(yīng)用中存在一個(gè) ActionServlet 類,但是可以存在多個(gè)客戶化的 RequestProcessor 類,每個(gè)子應(yīng)用模塊都可以擁有單獨(dú)的 RequestProcessor 類。如果想修改 RequestProcessor 類的一些默認(rèn)功能,可以覆蓋 RequestProcessor 基類中的相關(guān)方法。

    ?

    <!--[if !supportLists]-->(a)???<!--[endif]-->RequestProcessor類的process()方法

    RequestProcessor 類的 process() 方法負(fù)責(zé)實(shí)際的預(yù)處理請(qǐng)求操作。

    RequestProcessor 類的 process() 方法一次執(zhí)行一下流程:

    (1) 調(diào)用 processMultipart() 方法。如果 HTTP 請(qǐng)求方式為 POST ,并且請(qǐng)求的 contentType 屬性以“ multipart/form-data ”開頭,標(biāo)準(zhǔn)的 HttpServletRequest 對(duì)象將被重新包裝,以方便處理“ multipart ”類型的 HTTP 請(qǐng)求。如果請(qǐng)求方式為 GET ,或者 contentType 屬性不是“ multipart ”,就直接返回原始的 HttpServletRequest 對(duì)象。

    (2) 調(diào)用 processPath() 方法,獲得請(qǐng)求 URI 的路徑,這一信息可用于選擇合適的 Struts Action 組件。

    (3) 調(diào)用 processLocale() 方法,當(dāng) ControllerConfig 對(duì)象的 locale 屬性為 true ,將讀取用戶請(qǐng)求中包含的 Locale 信息,然后把 Locale 實(shí)例保存在 session 范圍內(nèi)。

    (4) 調(diào)用 processContent() 方法,讀取 ControllerConfig 對(duì)象的 contentType 屬性,然后調(diào)用 response.setContentType(contentType) 方法,設(shè)置響應(yīng)結(jié)果的文檔類型和字符編碼。

    (5) 調(diào)用 processNoCache() 方法,讀取 ControllerConfig 對(duì)象的 nocache 屬性,如果 nocache 屬性為 true ,在響應(yīng)結(jié)果中將加入特定的頭參數(shù): Pragma Cache-Control Expires ,防止頁(yè)面被存儲(chǔ)在客戶瀏覽器的緩存中。

    (6) 調(diào)用 processPreprocess() 方法。該方法不執(zhí)行任何操作,直接返回 true 。子類可以覆蓋這個(gè)方法,執(zhí)行客戶化的預(yù)處理請(qǐng)求操作。

    (7) 調(diào)用 processMapping() 方法,尋找和用戶請(qǐng)求的 URI 匹配的 ActionMapping 。如果不存在這樣的 ActionMapping ,則向用戶返回恰當(dāng)?shù)腻e(cuò)誤消息。

    (8) 調(diào)用 processRoles() 方法,先判斷是否為 Action 配置了安全角色,如果配置了安全角色,就調(diào)用 isUserRole() 方法判斷當(dāng)前用戶是否具備必需的角色;如果不具備,就結(jié)束請(qǐng)求處理流程,向用戶返回恰當(dāng)?shù)腻e(cuò)誤消息。

    (9) 調(diào)用 processActionForm() 方法,先判斷是否為 ActionMapping 配置了 ActionForm ,如果配置了 ActionForm ,就先從 ActionForm 的存在范圍內(nèi)尋找該 ActionForm 實(shí)例;如果不存在,就創(chuàng)建一個(gè)實(shí)例。接下來(lái)把它保存在合適的范圍中,保存時(shí)使用的屬性 key ActionMapping name 屬性。

    (10) 調(diào)用 processActionForm() 方法。如果為 ActionMapping 配置了 ActionForm ,就先調(diào)用 ActionForm reset() 方法,再把請(qǐng)求中的表單數(shù)據(jù)組裝到 ActionForm 中。

    (11) 調(diào)用 processValidate() 方法,如果為 ActionMapping 配置了 ActionForm ,并且 ActionMapping validate 屬性為 true ,就調(diào)用 ActionForm validate() 方法。如果 validate() 方法返回的 ActionErrors 對(duì)象中包含 ActionMessage 對(duì)象,說(shuō)明表單驗(yàn)證失敗,就把 ActionErrors 對(duì)象存儲(chǔ)在 request 范圍內(nèi),再把請(qǐng)求轉(zhuǎn)發(fā)到 ActionMapping input 屬性指定的 Web 組件。如果 ActionForm validate() 方法執(zhí)行表單驗(yàn)證成功,就繼續(xù)執(zhí)行下一步請(qǐng)求處理流程。

    (12) 調(diào)用 processForward() 方法,判斷是否在 ActionMapping 中配置了 forward 屬性。如果配置了這個(gè)屬性,就調(diào)用 RequestDispatcher forward() 方法,請(qǐng)求處理流程結(jié)束,否則繼續(xù)下一步。

    (13) 調(diào)用 processInclude() 方法,判斷是否在 ActionMapping 中配置了 include 屬性。如果配置了這個(gè)屬性,就調(diào)用 RequestDispatcher include() 方法,請(qǐng)求處理流程結(jié)束,否則繼續(xù)下一步。

    (14) 調(diào)用 processActionCreate() 方法,先判斷是否在 Action 緩存中存在這個(gè) Action 實(shí)例,如果不存在,就創(chuàng)建一個(gè) Action 實(shí)例,把它保存在 Action 緩存中。

    (15) 調(diào)用 processActionPerform() 方法,該方法再調(diào)用 Action 實(shí)例的 execute() 方法。 execute() 方法位于 try/catch 代碼中,以便捕獲異常。

    (16) 調(diào)用 processActionForward() 方法,把 Action execute() 方法返回的 ActionForward 對(duì)象作為參數(shù)傳給它。 processActionForward() 根據(jù) ActionForward 對(duì)象包含的請(qǐng)求轉(zhuǎn)發(fā)信息來(lái)執(zhí)行請(qǐng)求轉(zhuǎn)發(fā)或重定向。

    ?

    <!--[if !supportLists]-->(b)???<!--[endif]-->擴(kuò)展RequestProcessor

    開發(fā)人員可以很方便地創(chuàng)建客戶化的 RequestProcessor 類。

    Struts 配置文件中, <controller> 元素的 processorClass 屬性 RequestProcessor 類。

    ?

    ?

    3 Action

    Action 類是用戶請(qǐng)求和業(yè)務(wù)邏輯之間的橋梁。每個(gè) Action 充當(dāng)客戶的一項(xiàng)業(yè)務(wù)代理。在 RequestProcessor 類預(yù)處理請(qǐng)求時(shí),在創(chuàng)建了 Action 的實(shí)例后,就調(diào)用自身的 processActionPerform() 方法,該方法再調(diào)用 Action 類的 execute() 方法。

    Action execute() 方法調(diào)用模型的業(yè)務(wù)方法,完成用戶請(qǐng)求的業(yè)務(wù)邏輯,然后根據(jù)執(zhí)行結(jié)果把請(qǐng)求轉(zhuǎn)發(fā)給其他合適的 Web 組件。

    ?

    <!--[if !supportLists]-->(a)???<!--[endif]-->Action類緩存

    為了確保線程安全 (thread-safe) ,在一個(gè)應(yīng)用的生命周期中, Struts 框架只會(huì)為每個(gè) Action 類創(chuàng)建一個(gè) Action 實(shí)例。所有的客戶請(qǐng)求共享一個(gè) Action 實(shí)例,并且所有請(qǐng)求線程可以同時(shí)執(zhí)行它的 execute() 方法。

    RequestProcessor 類包含一個(gè) HashMap ,作為存放所有 Action 實(shí)例的緩存,每個(gè) Action 實(shí)例在緩存中存放的屬性 key Action 類名。在 RequestProcessor 類的 processActionCreate() 方法中,首先檢查在 HashMap 中是否存在 Action 實(shí)例,如果存在,就返回這個(gè)實(shí)例;否則,就創(chuàng)建一個(gè)新的 Action 實(shí)例。創(chuàng)建 Action 實(shí)例的代碼位于同步代碼塊中,以保證只有一個(gè)線程創(chuàng)建 Action 實(shí)例。一旦線程創(chuàng)建了 Action 實(shí)例并把它存放到 HashMap 中,以后所有的線程就會(huì)直接使用這個(gè)緩存中的實(shí)例。

    ?

    <!--[if !supportLists]-->(b)???<!--[endif]-->ActionForward

    Action 類的 execute() 方法返回一個(gè) ActionForward 對(duì)象。 ActionForward 對(duì)象代表了 Web 資源的邏輯抽象,這里的 Web 資源可以是 JSP 頁(yè)、 Java Servlet Action 。從 execute() 方法中返回 ActionForward 對(duì)象有兩種方法:

    · execute() 方法中動(dòng)態(tài)創(chuàng)建一個(gè) ActionForward 實(shí)例

    · Struts 配置文件中配置 <forward> 元素。

    ??? ??? 配置了 <forward> 元素后,在 Struts 框架初始化時(shí)就會(huì)創(chuàng)建存放 <forward> 元素;

    ?? execute() 方法中只需調(diào)用 ActionMapping 實(shí)例的 findForward() 方法,來(lái)獲取特定的 ActionForward 實(shí)例。 findForward() 方法先調(diào)用 findForwardConfig() 方法,在 Action 級(jí)別(即 <action> 元素內(nèi)的 <forward> 子元素)尋找匹配的 ActionForward 對(duì)象。如果沒有,再在全局級(jí)別(即 <global-forwards> 元素內(nèi)的 <forward> 子元素)中尋找匹配的 ActionForward 對(duì)象。如果找到,就返回該 ActionForward 對(duì)象。如果 findForward() 方法沒有找到匹配的 ActionForward 對(duì)象,它不會(huì)拋出異常,而是返回 null 。在瀏覽器端,用戶將收到一個(gè)空白頁(yè)。

    采用第二種方式,無(wú)需在程序中硬編碼來(lái)指定轉(zhuǎn)發(fā)資源的無(wú)力路徑,而是在配置文件中配置轉(zhuǎn)發(fā)資源,程序中秩序引用轉(zhuǎn)發(fā)資源的邏輯名即可,這提高了應(yīng)用的靈活性和可維護(hù)性。

    ?

    <!--[if !supportLists]-->(c)???<!--[endif]-->創(chuàng)建支持多線程的Action

    Struts 應(yīng)用的生命周期中,只會(huì)為每個(gè) Action 類創(chuàng)建一個(gè)實(shí)例,所有的客戶請(qǐng)求共享這個(gè)實(shí)例。因此,必需保證在多線程環(huán)境中, Action 也能正常工作。保證線程安全的重要元素是在 Action 類中僅僅使用局部變量,謹(jǐn)慎地使用實(shí)例變量。

    如果在 Action execute() 方法中定義了局部變量,對(duì)于每個(gè)調(diào)用 execute() 方法的線程, Java 虛擬機(jī)會(huì)在每個(gè)線程的堆棧中創(chuàng)建局部變量,因此每個(gè)線程擁有獨(dú)立的局部變量,不會(huì)被其他線程共享。當(dāng)線程執(zhí)行完 execute() 方法時(shí),它的局部變量就會(huì)被銷毀。

    如果在 Action 類中定義了實(shí)例變量,那么在 Action 實(shí)例的整個(gè)生命周期中,這個(gè)實(shí)例變量被所有的請(qǐng)求線程共享。因此不能在 Action 類中定義代表特定客戶狀態(tài)的實(shí)例變量。

    Action 類中定義的實(shí)例變量代表了可以被所有請(qǐng)求線程訪問(wèn)的共享資源。為了避免共享資源的競(jìng)爭(zhēng),在必要的情況下,需要采用 Java 同步機(jī)制對(duì)訪問(wèn)共享資源的代碼塊進(jìn)行同步。

    ?

    (d)Action 類的安全

    在某些情況下,如果 Action 類執(zhí)行的功能非常重要,則只允許具有特定權(quán)限的用戶才能訪問(wèn)該 Action 。為了防止未授權(quán)的用戶來(lái)訪問(wèn) Action ,可以在配置 Action 時(shí)指定安全角色。

    <action> 元素的 roles 屬性指定訪問(wèn)這個(gè) Action 的用戶必須具備的安全角色,多個(gè)角色之間以逗號(hào)隔開。

    RequestProcessor 類在預(yù)處理請(qǐng)求時(shí)會(huì)調(diào)用自身的 processRoles() 方法,該方法先檢查在配置文件中是否未 Action 配置了安全角色,如果配置了安全角色,就調(diào)用 HttpServletRequest isUserInRole() 方法,來(lái)判斷用戶是否具備了必要的安全角色。如果不具備,就直接向客戶端返回錯(cuò)誤。

    ?

    ?

    ?

    使用內(nèi)置的 StrutsAction

    ?

    Struts 提供了一些現(xiàn)成的 Action 類,在 Struts 應(yīng)用中直接使用這些 Action 類可以大大節(jié)省開發(fā)時(shí)間。

    ?

    1 org.apache.struts.actions.ForwardAction

    ? JSP 網(wǎng)頁(yè)中,盡管可以直接通過(guò) <jsp:forward> 標(biāo)簽把請(qǐng)求轉(zhuǎn)發(fā)給其他 Web 組件,但是 Struts 框架提倡先把請(qǐng)求轉(zhuǎn)發(fā)給控制器,再由控制器來(lái)負(fù)責(zé)請(qǐng)求轉(zhuǎn)發(fā)。

    ?

    ? 有控制器來(lái)負(fù)責(zé)請(qǐng)求轉(zhuǎn)發(fā)有以下一些優(yōu)點(diǎn):

    ·控制器具有預(yù)處理請(qǐng)求功能,它能夠選擇正確的子應(yīng)用模塊來(lái)處理請(qǐng)求,并且把子應(yīng)用模塊的 ModuleConfig MessageResources 對(duì)象存放在 request 范圍內(nèi)。這樣,請(qǐng)求轉(zhuǎn)發(fā)的目標(biāo) Web 組件就可以正常地訪問(wèn) ModuleConfig MessageResources 對(duì)象。

    ·如果 JSP 頁(yè)面中包含 HTML 表單,那么控制器能夠創(chuàng)建和這個(gè)表單對(duì)應(yīng)的 ActionForm 對(duì)象,把用戶輸入表單數(shù)據(jù)組裝到 ActionForm 中。如果 <action> 元素的 validate 屬性為 true ,那么還會(huì)調(diào)用 ActionForm 的表單驗(yàn)證方法。控制器把 ActionForm 對(duì)象存放在 request session 范圍內(nèi),這樣請(qǐng)求轉(zhuǎn)發(fā)的目標(biāo) Web 組件也可以訪問(wèn) ActionForm

    · JSP 網(wǎng)頁(yè)之間直接相互轉(zhuǎn)發(fā)違背了 MVC 的分層原則,按照 MVC 設(shè)計(jì)思想,控制器負(fù)責(zé)處理所有請(qǐng)求,然后選擇適當(dāng)?shù)囊晥D組件返回給用戶,如果直接讓 JSP 相互調(diào)用,控制器就失去了流程控制作用。

    ?

    ? 對(duì)于用戶自定義的 Action 類,既可以負(fù)責(zé)請(qǐng)求轉(zhuǎn)發(fā),還可以充當(dāng)客戶端的業(yè)務(wù)代理,如果僅僅需要 Action 類提供請(qǐng)求轉(zhuǎn)發(fā)功能,則可以使用 org.apache.struts.actions.ForwardAction 類。 ForwardAction 類專門用于轉(zhuǎn)發(fā)請(qǐng)求,不執(zhí)行任何其他業(yè)務(wù)操作。

    ? ActionServlet 把請(qǐng)求轉(zhuǎn)發(fā)給 ForwardAction ForwardAction 再把請(qǐng)求轉(zhuǎn)發(fā)給 <action> 元素中 parameter 屬性指定的 Web 組件。總之,在 Web 組件之間通過(guò) ForwardAction 類來(lái)進(jìn)行請(qǐng)求轉(zhuǎn)發(fā),可以充分利用 Struts 控制器的預(yù)處理請(qǐng)求功能。此外,也可以通過(guò) <action> 元素的 forward 屬性來(lái)實(shí)現(xiàn)請(qǐng)求轉(zhuǎn)發(fā)。

    ?

    2 org.apache.struts.actions.IncludeAction

    ? JSP 網(wǎng)頁(yè)中,盡管可以直接通過(guò) <include> 指令包含另一個(gè) Web 組件,但是 Struts 框架提倡先把請(qǐng)求轉(zhuǎn)發(fā)給控制器,再由控制器來(lái)負(fù)責(zé)包含其他 Web 組件。 IncludeAction 類提供了包含其他 Web 組件的功能。與 ForwardAction 一樣, Web 組件通過(guò) IncludeAction 類來(lái)包含另一個(gè) Web 組件,可以充分利用 Struts 控制器的預(yù)處理功能。

    <action> paramter 屬性指定需要包含的 Web 組件。此外,也可以通過(guò) <action> 元素的 include 屬性來(lái)包含 Web 組件。

    ?

    3 org.apache.struts.actions.DispatchAction

    ? 通常,在一個(gè) Action 類中,只能完成一種業(yè)務(wù)操作,如果希望在同一個(gè) Action 類中完成一組相關(guān)的業(yè)務(wù)操作,可以使用 DispatchAction 類。

    ? 創(chuàng)建一個(gè)擴(kuò)展 DispatchAction 類的子類,不必覆蓋 execute() 方法,而是創(chuàng)建一些實(shí)現(xiàn)實(shí)際業(yè)務(wù)操作的方法,這些業(yè)務(wù)方法都應(yīng)該和 execute() 方法具有同樣的方法簽名,即他們的參數(shù)和返回類型都應(yīng)該相同,此外也應(yīng)該聲明拋出 Exception

    ? 在配置 DispatchAction 類時(shí),需要把 parameter 屬性設(shè)置為“ method ”。設(shè)置之后,當(dāng)用戶請(qǐng)求訪問(wèn) DispatchAction 時(shí),應(yīng)該提供 method 請(qǐng)求參數(shù)。

    ?

    4 org.apache.struts.actions.LookupDispatchAction

    LookupDispatchAction 類是 DispatchAction 的子類,在 LookupDispatchAction 類中也可以定義多個(gè)業(yè)務(wù)方法。通常 LookupDispatchAction 主要應(yīng)用于在一個(gè)表單中有多個(gè)提交按鈕,而這些按鈕又有一個(gè)共同的名字的場(chǎng)合,這些按鈕的名字和具體的 ActionMapping parameter 屬性值相對(duì)應(yīng)。

    Struts 配置文件中配置 LookUpDispatchAction

    <action> 元素中,設(shè)置 parameter 屬性時(shí),需要使它和 <html:submit> 標(biāo)簽的 property 屬性保持一致。

    ?

    5 org.apache.struts.actions.SwitchAction

    SwitchAction 類用于子應(yīng)用模塊之間的切換。對(duì)于請(qǐng)求訪問(wèn) SwitchAction URL ,需要提供兩個(gè)參數(shù):

    · prefix :指定子應(yīng)用模塊的前綴,以“ / ”開頭,默認(rèn)子應(yīng)用模塊的前綴為空字符串“”。

    · page :指定被請(qǐng)求 Web 組件的 URI ,只需指定相對(duì)于被切換后的子應(yīng)用模塊的相對(duì)路徑。

    ?

    ?

    利用 Token 解決重復(fù)提交

    ?

    ? 在某些情況下,如果用戶對(duì)同一個(gè) HTML 表單多次提交, Web 應(yīng)用必需能夠判斷用戶的重復(fù)提交行為,以作出相應(yīng)的處理。

    ? 可以利用同步令牌( Token )機(jī)制來(lái)解決 Web 應(yīng)用中重復(fù)提交的問(wèn)題, Struts 也給出了一個(gè)參考實(shí)現(xiàn)。 org.apache.struuts.action.Action 類中提供了一系列和 Token 相關(guān)的方法:

    ? · protected boolean isTokenValid(javax.servlet.http.HttpServletRequestrequest)

    判斷存儲(chǔ)在當(dāng)前用戶會(huì)話中的令牌值和請(qǐng)求參數(shù)中的令牌值是否匹配。如果匹配,就返回 true ,否則返回 false 。只要符合一下情況之一,就返回 false

    ·不能存在 HttpSession 對(duì)象。

    ·在 session 范圍內(nèi)沒有保存令牌值。

    ·在請(qǐng)求參數(shù)中沒有令牌值

    ·存儲(chǔ)在當(dāng)前用戶 session 范圍內(nèi)的令牌值和請(qǐng)求參數(shù)中的令牌值不匹配。

    ? · protected voidresetToken(javax.servlet.http.HttpServletRequest request)

    從當(dāng)前 session 范圍內(nèi)刪除令牌屬性。

    ? · protected voidsaveToken(javax.servlet.http.HttpServletRequest request)

    創(chuàng)建一個(gè)新的令牌,并把它保存在當(dāng)前 session 范圍內(nèi)。如果 HttpSession 對(duì)象不存在,就首先創(chuàng)建一個(gè) HttpSession 對(duì)象。

    ?

    ? 具體的 Token 處理邏輯由 org.apache.struts.util.TokenProcessor 類來(lái)完成,它的 generateToken(request) 方法根據(jù)用戶會(huì)話 ID 和當(dāng)前系統(tǒng)時(shí)間來(lái)生成一個(gè)唯一的令牌。

    ?

    ?

    實(shí)用類

    ?

    ? 在創(chuàng)建 Web 應(yīng)用時(shí),有許多檢索和處理 HTTP 請(qǐng)求的操作時(shí)重復(fù)的。為了提高應(yīng)用代碼的可重用性,減少冗余, Struts 框架提供了一組提供這些通用功能的實(shí)用類,它們可以被所有的 Struts 應(yīng)用共享。

    ?

    1 RequestUtils

    org.apache.struts.util.RequestUtils Struts 控制框架提供了一些處理請(qǐng)求的通用方法。 RequestUtils 類中的所有方法都是線程安全的,在這個(gè)類中沒有定義任何實(shí)例變量,所有的方法都被聲明為 static 類型。因此,不必創(chuàng)建 RequestUtils 類的實(shí)例,可以直接通過(guò)類名來(lái)訪問(wèn)這些方法。

    RequestUtils 類的常用方法

    方法

    描述

    absoluteURL(HttpServletRequest request,String utl)

    創(chuàng)建并返回絕對(duì) URL 路徑,參數(shù) path 指定相對(duì)于上下文( context-relative )的相對(duì)路徑

    createActionForm(HttpServletRequest request, ActionMapping mapping, ModuleConfig moduleConfig, ActionServlet servlet)

    先從 request session 范圍內(nèi)查找該 ActionForm ,如果存在,就直接將它返回,否則先創(chuàng)建它的實(shí)例,把它保存在 request session 范圍內(nèi),再把它返回。 mapping 參數(shù)包含了 <action> 元素的配置信息,例如它的 scope 屬性指定 ActionForm 的范圍

    populate(Object bean, HttpServletRequest request)

    HTTP 請(qǐng)求中的參數(shù)值組裝到指定的 JavaBean 中,請(qǐng)求的參數(shù)名和 JavaBean 的屬性名匹配。當(dāng) ActionServlet 把用戶輸入的表單數(shù)據(jù)組裝到 ActionForm 中時(shí),就調(diào)用此方法

    ?

    2 TagUtils

    org.apache.struts.taglib.TagUtil 類為 JSP 標(biāo)簽處理類提供了許多實(shí)例方法,如果要使用 TagUtils 類,首先應(yīng)調(diào)用 TagUtils.getInstance() 方法,獲得 TagUtils 類的實(shí)例, getInstance() 方法為靜態(tài)方法。

    TagUtils 類的常用方法

    方法

    描述

    getInstance()

    返回一個(gè) TagUtils 的實(shí)例。該方法為靜態(tài)的,如果要在程序中獲得 TagUtils 的實(shí)例,可以調(diào)用 TagUtils.getInstance() 方法

    getActionMessages(PageContext pageContext, String paramName)

    調(diào)用 pageContext.findAttribute(paramName) 方法,從 page, request, session application 范圍內(nèi)減縮并返回 ActionMessages 對(duì)象,參數(shù) paramName 指定檢索 ActionMessages 對(duì)象的屬性 key

    getModuleConfig(PageContext pageContext)

    返回 ModuleConfig 對(duì)象,如果不存在,就返回 null

    lookup(PageContext pageContext, String name, String scope)

    返回特定范圍內(nèi)的 JavaBean 。參數(shù) scope 指定 JavaBean 的所在范圍, name 參數(shù)指定 JavaBean 在特定范圍內(nèi)的名字

    message(PageContext pageContext, String bundle, String locale, String key)

    從指定的 Resource Bundle 中返回一條消息文本,參數(shù) locale 指定 Locale ,參數(shù) key 指定消息 key

    write(PageContext pageContext, String text)

    向網(wǎng)頁(yè)上輸入特定的文本,參數(shù) text 用于指定文本內(nèi)容

    ?

    3 ModuleUtils

    org.apache.struts.taglib.ModuleUtils 類提供了處理子應(yīng)用模塊的實(shí)用方法,如果要使用 ModuleUtils 類,首先應(yīng)該調(diào)用 ModuleUtils.getInstance() 方法,獲得 ModuleUtils 類的實(shí)例, getInstance() 方法為靜態(tài)方法。

    ModuleUtils 類的常用方法

    方法

    描述

    getInstance()

    返回一個(gè) ModuleUtils 的實(shí)例。該方法為靜態(tài)的,如果要在程序中獲得 ModuleUtils 的實(shí)例,可以調(diào)用 ModuleUtils.getInstance() 方法。

    getModuleConfig(javax.servlet.http.HttpervletRequest request)

    request 范圍內(nèi)檢索并返回 ModuleConfig 對(duì)象

    getModuleConfig(java.lang.String prefix, javax.servlet.ServletContext context)

    application 范圍內(nèi)檢索并返回 ModuleConfig 對(duì)象,參數(shù) prefix 指定子應(yīng)用模塊名的前綴

    getModuleName(javax.servlet.http.HttpServletRequest request, javax.servlet.ServletContext context)

    返回請(qǐng)求訪問(wèn)的子應(yīng)用模塊的名字

    selectModule(javax.servlet.http.HttpServletRequest request, javax.servlet.ServletContext context)

    選擇請(qǐng)求訪問(wèn)的子應(yīng)用模塊,把和子應(yīng)用模塊相關(guān)的 ModuleConfig MessageResources 對(duì)象存儲(chǔ)到 request 范圍中

    ?

    4 Globals

    org.apache.struts.Globals 類提供一組公共類型的靜態(tài)常量,被用作在特定范圍內(nèi)存放 JavaBean 的屬性 key

    Globals 類中定義的常量

    方法

    描述

    ACTION_SERVLET_KEY

    代表在 application 范圍內(nèi)存放 ActionServlet 實(shí)例的屬性 key

    DATA_SOURCE_KEY

    代表在 application 范圍內(nèi)存放默認(rèn)的 DataSource 實(shí)例的屬性 key

    ERROR_KEY

    代表在 request 范圍內(nèi)存放 ActionErrors 實(shí)例的屬性 key

    LOCALE_KEY

    代表在 session 范圍內(nèi)存放 Locale 實(shí)例的屬性 key

    MAPPING_KEY

    代表在 request 范圍內(nèi)存放 ActionMapping 實(shí)例的屬性 key

    MESSAGE_KEY

    代表在 request 范圍內(nèi)存放 ActionMessages 實(shí)例的屬性 key

    MESSAGES_KEY

    代表在 application 范圍內(nèi)存放各個(gè)子應(yīng)用模塊的 MessageResources 實(shí)例的屬性 key 的前綴

    MODULE_KEY

    代表在 application 范圍內(nèi)存放各個(gè)子應(yīng)用模塊的 ModuleConfig 實(shí)例的屬性 key 的前綴

    REQUEST_PROCESSOR_KEY

    代表在 application 范圍內(nèi)存放各個(gè)子應(yīng)用模塊的 RequestProcessor 實(shí)例的屬性 key 的前綴



    閱讀材料:《精通Struts:基于MVC的Java Web設(shè)計(jì)與開發(fā)》


    Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=372708

    posted on 2006-12-20 16:08 蘆葦 閱讀(415) 評(píng)論(0)  編輯  收藏 所屬分類: Struts
    主站蜘蛛池模板: 三上悠亚亚洲一区高清| 97国产免费全部免费观看| 国产成人yy免费视频| 国产免费小视频在线观看| 久久亚洲精品国产精品黑人| 亚洲午夜无码久久久久小说| 两个人看的www视频免费完整版| 皇色在线视频免费网站| 亚洲色精品88色婷婷七月丁香 | 亚洲AV综合色区无码一区| 国产精品亚洲一区二区麻豆| 中国一级特黄的片子免费 | 亚洲网站在线观看| 亚洲国产欧美国产综合一区| 一个人免费视频观看在线www| 无码人妻精品一二三区免费| 久久亚洲国产午夜精品理论片 | 国产一精品一av一免费爽爽| 日本一区二区三区日本免费| 亚洲精选在线观看| yy一级毛片免费视频| 成人免费午夜在线观看| 亚洲成年轻人电影网站www| 免费精品国自产拍在线播放| 国产成人无码免费看视频软件| 亚洲精品乱码久久久久久蜜桃不卡| 亚洲人成网亚洲欧洲无码| 99re热精品视频国产免费| 亚洲性日韩精品国产一区二区| 久久乐国产综合亚洲精品| 三年片在线观看免费大全电影| 亚洲片国产一区一级在线观看| 亚洲色中文字幕在线播放| 91精品啪在线观看国产线免费| 国产亚洲成人久久| 国产成人综合久久精品亚洲| 91视频国产免费| 亚洲黄色片在线观看| 热99RE久久精品这里都是精品免费 | 一级一级一片免费高清| 最新中文字幕电影免费观看|