控制器(StrutsPrepareAndExecuteFilter或FilterDispatcher)
==========================================================================
《Struts2體系結構圖以及詳解》
【http://blog.csdn.net/tender001/article/details/7582146】
FilterDispatcher是控制器的核心,就是mvc中c控制層的核心。
下面粗略的分析下我理解的FilterDispatcher工作流程和原理:FilterDispatcher進行初始化並啟用核心doFilter。
du.serviceAction(request, response, servletContext, mapping);
//這個方法詢問ActionMapper是否需要調用某個Action來處理這個(request)請求,如果ActionMapper決定需要調用某個Action,FilterDispatcher把請求的處理交給ActionProxy
ActionProxy通過Configuration Manager(struts.xml)詢問框架的配置文件,找到需要調用的Action類.
ActionProxy創建一個ActionInvocation的實例,同時ActionInvocation通過代理模式調用Action。
ActionProxy是Action的一個代理類,也就是說Action的調用是通過ActionProxy實現的,其實就是調用了ActionProxy.execute()方法,而該方法又調用了ActionInvocation.invoke()方法。歸根到底,最后調用的是DefaultActionInvocation.invokeAction()方法。
但在調用之前ActionInvocation會根據配置加載Action相關的所有Interceptor。
ActionInvocation 是Xworks 中Action 調度的核心。而對Interceptor 的調度,也正是由ActionInvocation負責。
ActionInvocation 是一個接口,而DefaultActionInvocation 則是Webwork 對ActionInvocation的默認實現。
Interceptor 的調度流程大致如下:
1. ActionInvocation初始化時,根據配置,加載Action相關的所有Interceptor。
2. 通過ActionInvocation.invoke方法調用Action實現時,執行Interceptor。
Interceptor將很多功能從我們的Action中獨立出來,大量減少了我們Action的代碼,獨立出來的行為具有很好的重用性。XWork、WebWork的許多功能都是有Interceptor實現,可以在配置文件中組裝Action用到的Interceptor,它會按照你指定的順序,在Action執行前后運行。
那么什么是攔截器。
攔截器就是AOP(Aspect-Oriented Programming)的一種實現。(AOP是指用於在某個方法或字段被訪問之前,進行攔截然后在之前或之后加入某些操作。)
攔截器的例子這里就不展開了。
一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果。如上文中將結構返回“add.jsp”,但大部分時候都是返回另外一個action,那么流程又得走一遍。
==========================================================================
==========================================================================
過濾器:
filter功能:用戶可以改變一個request和修改一個response
Filter 不是一個servlet,它不能產生一個response,它能夠在一個request到達servlet之前預處理request,也可以在離開servlet時處理response.換種說法,filter其實是一個”servlet chaining”(servlet 鏈).
一個filter 包括:
1. 在servlet被調用之前截獲;
2. 在servlet被調用之前檢查servlet request;
3. 根據需要修改request頭和request數據;
4. 根據需要修改response頭和response數據;
5. 在servlet被調用之后截獲.
通常我們所訪問的資源是一個servlet或jsp頁面,而jsp其實是一個被封裝了的servlet(每個jsp執行前都會被轉化為一個標准的servlet,這點若還有不明白的請自己到網上查一下吧),於是我們就可以統一地認為我們每次訪問的都是一個Servlet,而每當我們訪問一個servlet時,web容器都會調用該Servlet的service方法去處理請求。而在service方法又會根據請求方式的不同(Get/Post)去調用相應的doGet()或doPost()方法,實際處理請求的就是這個doGet或doPost方法。寫過servlet的朋友都應該知道,我們在doGet(或doPost)方法中是通過response.getWriter()得到客戶端的輸出流對象,然后用此對象對客戶進行響應。
到這里我們就應該理解了過濾器的執行流程了:執行第一個過濾器的chain.doFilter()之前的代碼——>第二個過濾器的chain.doFilter()之前的代碼——>……——>第n個過濾器的chain.doFilter()之前的代碼——>所請求servlet的service()方法中的代碼——>所請求servlet的doGet()或doPost()方法中的代碼——>第n個過濾器的chain.doFilter()之后的代碼——>……——>第二個過濾器的chain.doFilter()之后的代碼——>第一個過濾器的chain.doFilter()之后的代碼。
==========================================================================
《過濾器與攔截器》
1、攔截器是基於java反射機制的,而過濾器是基於函數回調的。
2、過濾器依賴與servlet容器,而攔截器不依賴與servlet容器。
3、攔截器只能對Action請求起作用,而過濾器則可以對幾乎所有請求起作用。
4、攔截器可以訪問Action上下文、值棧里的對象,而過濾器不能。
5、在Action的生命周期中,攔截器可以多次調用,而過濾器只能在容器初始化時被調用一次。
