如何用源碼分析Struts2請求處理及過程

這期內(nèi)容當中小編將會給大家?guī)碛嘘P(guān)如何用源碼分析Struts2請求處理及過程,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

十多年的恒山網(wǎng)站建設經(jīng)驗,針對設計、前端、開發(fā)、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。全網(wǎng)營銷推廣的優(yōu)勢是能夠根據(jù)用戶設備顯示端的尺寸不同,自動調(diào)整恒山建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設計,從而大程度地提升瀏覽體驗。成都創(chuàng)新互聯(lián)從事“恒山網(wǎng)站設計”,“恒山網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。

1.1 Struts2請求處理

1. 一個請求在Struts2框架中的處理步驟:

a) 客戶端初始化一個指向Servlet容器的請求;

b) 根據(jù)Web.xml配置,請求首先經(jīng)過ActionContextCleanUp過濾器,其為可選過濾器,這個過濾器對于Struts2和其他框架的集成很有幫助(SiteMesh Plugin),主要清理當前線程的ActionContext和Dispatcher;

c) 請求經(jīng)過插件過濾器,如:SiteMesh、etc等過濾器;

d) 請求經(jīng)過核心過濾器FilterDispatcher,執(zhí)行doFilter方法,在該方法中,詢問ActionMapper來決定這個請求是否需要調(diào)用某個Action;

e) 如果ActionMapper決定需要調(diào)用某個Action,則ActionMapper會返回一個ActionMapping實例(存儲Action的配置信息),并創(chuàng)建ActionProxy(Action代理)對象,將請求交給代理對象繼續(xù)處理;

f) ActionProxy對象根據(jù)ActionMapping和Configuration Manager詢問框架的配置文件,找到需要調(diào)用的Action類;

g) ActionProxy對象創(chuàng)建時,會同時創(chuàng)建一個ActionInvocation的實例;

h) ActionInvocation實例使用命名模式來調(diào)用,在調(diào)用Action的過程前后,涉及到相關(guān)攔截器(Intercepter)的調(diào)用;

i) 一旦Action執(zhí)行完畢,ActionInvocation實例負責根據(jù)struts.xml中的配置創(chuàng)建并返回Result。Result通常是一個需要被表示的JSP或者FreeMarker的模版,也可能是另外的一個Action鏈;

j) 如果要在返回Result之前做些什么,可以實現(xiàn)PreResultListener接口,PreResultListener可以在Interceptor中實現(xiàn),也可以在Action中實現(xiàn);

k) 根據(jù)Result對象信息,生成用戶響應信息response,在生成響應過程中可以使用Struts2 框架中繼承的標簽,在此過程中仍會再次涉及到ActionMapper;

2. Struts2請求處理示意圖:

如何用源碼分析Struts2請求處理及過程

1.2 Struts2請求處理源碼分析

當用戶向Struts2發(fā)送請求時,F(xiàn)ilterDispatcher的doFilter()方法自動調(diào)用,doFilter()方法處理請求過程,如下:

1. 創(chuàng)建值棧對象stack;

2. 創(chuàng)建Action上下文對象;

3. 對請求進行重新封裝,此次封裝根據(jù)請求內(nèi)容的類型不同,返回不同的對象:

如果為multipart/form-data類型,則返回MultiPartRequestWrapper類型的對象,該對象服務于文件上傳,否則返回StrutsRequestWrapper類型的對象,MultiPartRequestWrapper是StrutsRequestWrapper的子類,而這兩個類都是HttpServletRequest接口的實現(xiàn)。

4. 通過actionMapper.getMapping()獲得ActionMapping對象,Action的配置信息存儲在ActionMapping對象中(Action的配置信息:Action的name、namespace和要調(diào)用的方法method)。相關(guān)代碼如下圖所示:

如何用源碼分析Struts2請求處理及過程

以上代碼,活動圖如下:

如何用源碼分析Struts2請求處理及過程

5. 如果getMapping()方法返回ActionMapping對象為null,則FilterDispatcher認為用戶請求不是Action,此時FilterDispatcher會首先分析:

如果請求以/struts開頭,會自動查找在web.xml文件中配置的packages初始化參數(shù),F(xiàn)ilterDispatcher會將packages參數(shù)值包下的文件當作靜態(tài)資源處理,即直接在頁面上顯示文件內(nèi)容。

如果用戶請求的資源不是以/struts開頭—可能是.jsp文件,也可能是.html文件,則通過過濾器鏈繼續(xù)往下傳送,直到到達請求的資源為止。

6. 如果getMapping()方法返回有效的ActionMapping對象,則被認為正在請求某個Action,將調(diào)用Dispatcher.serviceAction(request, response, servletContext, mapping)方法。

以上六步,相關(guān)代碼如下圖所示:

如何用源碼分析Struts2請求處理及過程

如何用源碼分析Struts2請求處理及過程

以上代碼,活動圖如下:

如何用源碼分析Struts2請求處理及過程

7. 請求進入dispatcher.serviceAction(request,response,servletContext,mapping)方法中:

a) 將相關(guān)對象信息封裝為Map(如:HttpServletRequest、Http parameters、HttpServletResponse、HttpSession、ServletContext、ActionMapping等對象信息),并存入到執(zhí)行上下文Map中,返回執(zhí)行上下文Map對象extraMap;

b) 獲取mapping對象中存儲的action命名空間、name屬性、method屬性等信息;

c) 加載并解析Struts2配置文件,如果沒有人為配置,默認按順序加載struts-default.xml、struts-plugin.xml、struts.xml,將action配置、result配置、interceptor配置,解析并存入至config對象中,返回文件配置對象config;

d) 根據(jù)執(zhí)行上下文Map、action命名空間、name屬性、method屬性等創(chuàng)建用戶Action的代理對象;

e) 執(zhí)行Action代理對象proxy.execute()方法,并轉(zhuǎn)向結(jié)果;

以上步驟相關(guān)代碼,如圖所示:

如何用源碼分析Struts2請求處理及過程

8. 執(zhí)行Action代理對象proxy.execute()方法,該方法的執(zhí)行,其實就是調(diào)用了invocation.invoke()方法,如下圖所示:

如何用源碼分析Struts2請求處理及過程

9. 執(zhí)行invocation.invoke()方法,實現(xiàn)了截攔器的遞歸調(diào)用和執(zhí)行Action的execute()方法,DefaultActionInvocation.invoke()方法中代碼,如下圖所示:

如何用源碼分析Struts2請求處理及過程

在以上代碼中,并未看出攔截器的遞歸調(diào)用,其實是否遞歸調(diào)用,是由程序員來控制的,遞歸調(diào)用實現(xiàn)很簡單:

a) 首先看下Interceptor接口定義:

如何用源碼分析Struts2請求處理及過程

b) 所有的截攔器必須實現(xiàn)intercept方法,而該方法的參數(shù)恰恰又是ActionInvocation,所以如果在intercept方法中調(diào)用invocation.invoke(),則會繼續(xù)從Action的Intercepor列表中找到下一個截攔器執(zhí)行,依此遞歸調(diào)用Intercepor;

Struts2中的日志攔截器LoggingInterceptor,如下圖所示:

如何用源碼分析Struts2請求處理及過程

c) 攔截器遞歸調(diào)用活動圖,如下所示:

如何用源碼分析Struts2請求處理及過程

10. 在invocation.invoke()方法中,執(zhí)行攔截器、action并獲得resultCode完畢后,則會繼續(xù)執(zhí)行PreResultListener集合,并生成Result對象,實現(xiàn)PreResultListener接口,可在返回Result之前,做些自定義處理,如圖所示

如何用源碼分析Struts2請求處理及過程

在返回Result之前,通過PreResultListener實現(xiàn)自定義處理,常用的有兩種方式:一種在Interceptor中實現(xiàn),一種在Action實現(xiàn),如圖所示:

如何用源碼分析Struts2請求處理及過程

如何用源碼分析Struts2請求處理及過程

以上兩種方式,大家可以發(fā)現(xiàn)都是通過匿名內(nèi)部類的方式實現(xiàn),其實還有一種方式就是通過在攔截器中實現(xiàn)PreResultListener接口,并實現(xiàn)方法beforeResult方法,即可。如下圖所示:

如何用源碼分析Struts2請求處理及過程

11. ***,通過生成Result完成用戶響應;

以上1-11步,為Struts2處理請求的完整流程分析,其相關(guān)代碼調(diào)用流程,如下圖所示:

如何用源碼分析Struts2請求處理及過程

上述就是小編為大家分享的如何用源碼分析Struts2請求處理及過程了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)頁名稱:如何用源碼分析Struts2請求處理及過程
文章路徑:http://muchs.cn/article24/pisjje.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設、外貿(mào)網(wǎng)站建設手機網(wǎng)站建設、做網(wǎng)站、搜索引擎優(yōu)化、App開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設