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

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

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

    Struts2請求處理流程及源碼分析

    1.1 Struts2請求處理

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

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

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

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

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

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

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

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

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

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

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

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

    2. Struts2請求處理示意圖:

    clip_image002

    1.2 Struts2請求處理源碼分析

    當用戶向Struts2發送請求時,FilterDispatcher的doFilter()方法自動調用,doFilter()方法處理請求過程,如下:

    1. 創建值棧對象stack;

    2. 創建Action上下文對象;

    3. 對請求進行重新封裝,此次封裝根據請求內容的類型不同,返回不同的對象:

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

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

    clip_image004

    以上代碼,活動圖如下:

    clip_image006

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

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

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

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

    以上六步,相關代碼如下圖所示:

    clip_image008

    clip_image010

    以上代碼,活動圖如下:

    clip_image012

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

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

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

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

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

    e) 執行Action代理對象proxy.execute()方法,并轉向結果;

    以上步驟相關代碼,如圖所示:

    clip_image014

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

    clip_image016

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

    clip_image018

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

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

    clip_image020

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

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

    clip_image022

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

    clip_image024

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

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

    clip_image028

    clip_image030

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

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

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

    clip_image034

    posted on 2012-09-06 08:47 Mr.lu 閱讀(201) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導航

    統計

    常用鏈接

    留言簿(2)

    隨筆檔案

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲制服丝袜第一页| 亚洲宅男永久在线| 激情小说亚洲色图| 精品国产一区二区三区免费看 | 亚洲午夜一区二区三区| 最近2019中文字幕免费直播| 亚洲AV乱码一区二区三区林ゆな| 国产精品视频白浆免费视频| 亚洲一区二区中文| 免费能直接在线观看黄的视频| 亚洲精品白色在线发布| 成年女人色毛片免费看| 国产成人综合亚洲绿色| 亚洲国产精品不卡毛片a在线| 久久国产亚洲精品无码| 日韩人妻无码精品久久免费一| 亚洲成无码人在线观看| 黄色视屏在线免费播放| 亚洲成在人线av| 日韩毛片一区视频免费| 亚洲熟女一区二区三区| 最近中文字幕mv免费高清在线| 亚洲图片激情小说| 国产免费av片在线无码免费看| sihu国产精品永久免费| 亚洲黄色网站视频| 麻豆国产入口在线观看免费| 亚洲国产免费综合| 中文字幕亚洲第一在线| 日本免费人成黄页网观看视频| 亚洲国产福利精品一区二区| 免费毛片在线播放| 91视频免费观看| 国产精品亚洲综合五月天| 亚洲成a人片在线播放| 91av免费观看| 三级片免费观看久久| 久久久久亚洲AV成人片| 国产男女猛烈无遮挡免费视频 | 亚洲人和日本人jizz| 麻豆国产入口在线观看免费|