1. 程式人生 > >Struts 2詳細工作流程

Struts 2詳細工作流程

 Struts 2框架本身大致可以分為3個部分:核心控制器FilterDispatcher、業務控制器Action和使用者實現的企業業務邏輯元件。

3.1.1  核心控制器FilterDispatcher

核心控制器FilterDispatcher是Struts 2框架的基礎,包含了框架內部的控制流程和處理機制。業務控制器Action和業務邏輯元件是需要使用者來自己實現的。使用者在開發Action和業務邏輯元件的同時,還需要編寫相關的配置檔案,供核心控制器FilterDispatcher來使用。

Struts 2的工作流程相對於Struts 1要簡單,與WebWork框架基本相同,所以說Struts 2是WebWork的升級版本。Struts 2框架按照模組來劃分,可以分為Servlet Filters、Struts核心模組、攔截器和使用者實現部分。Struts 2框架結構圖如圖3.1所示。

圖3.1  Struts 2框架結構圖

一個請求在Struts 2框架中的處理大概分為以下幾個步驟。

 客戶端提交一個(HttpServletRequest)請求,如上文在瀏覽器中輸入http://localhost: 8080/bookcode/ch2/Reg.action就是提交一個(HttpServletRequest)請求。

 請求被提交到一系列(主要是3層)的過濾器(Filter),如(ActionContextCleanUp、其他過濾器(SiteMesh等)、FilterDispatcher)。注意:這裡是有順序的,先ActionContext CleanUp,再其他過濾器(Othter Filters、SiteMesh等),最後到FilterDispatcher。

  FilterDispatcher是控制器的核心,就是MVC的Struts 2實現中控制層(Controller)的核心。

  FilterDispatcher詢問ActionMapper是否需要呼叫某個Action來處理這個(HttpServlet Request)請求,如果ActionMapper決定需要呼叫某個Action,FilterDispatcher則把請求的處理交給ActionProxy。

  ActionProxy通過Configuration Manager(struts.xml)詢問框架的配置檔案,找到需要呼叫的Action類。例如,使用者註冊示例將找到UserReg類。

  ActionProxy建立一個ActionInvocation例項,同時ActionInvocation通過代理模式呼叫Action。但在呼叫之前,ActionInvocation會根據配置載入Action相關的所有Interceptor(攔截器)。

 一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果result。

Struts 2的核心控制器是FilterDispatcher,有3個重要的方法:destroy()、doFilter()和Init(),可以在Struts 2的下載資料夾中找到原始碼,如程式碼3.1所示。

程式碼3.1  核心控制器FilterDispatcher

publicclass FilterDispatcher implements StrutsStatics, Filter {

    
/**

     * 定義一個Log例項

     
*/


privatestaticfinal Log LOG = LogFactory.getLog(FilterDispatcher.class);

… ...

    
/**

     * 存放屬性檔案中的.STRUTS_I18N_ENCODING值

     
*/


    
privatestatic String encoding;

    
/**

     * 定義ActionMapper例項

     
*/


    
privatestatic ActionMapper actionMapper;

    
/**

     * 定義FilterConfig例項

     
*/


    
private FilterConfig filterConfig;

    
protected Dispatcher dispatcher;

    
/**

     * 建立一個預設的dispatcher,初始化filter

     * 設定預設的packages     *

     
*/


    
publicvoid init(FilterConfig filterConfig) throws ServletException {

     
this.filterConfig = filterConfig;

       dispatcher 
= createDispatcher(filterConfig);

        dispatcher.init();

        String param 
= filterConfig.getInitParameter("packages");

        String packages 
="org.apache.struts2.static template org.apache.struts2.interceptor.debugging";

        
if (param !=null{

            packages 
= param +""+ packages;

        }


        
this.pathPrefixes = parse(packages);

    }


    
//銷燬filter方法

   
publicvoid destroy() {

        
if (dispatcher ==null{

            LOG.warn(
"something is seriously wrong, Dispatcher is not initialized (null) ");

        }
else{

            dispatcher.cleanup();

        }


    }


    
/**

     * 處理一個Action或者資源請求

     * <p/>

     * filter嘗試將請求同action mapping相匹配

     * 如果找到,將執行dispatcher的serviceAction方法

     * 如果Action處理失敗, doFilter將建立一個異常

     * <p/>

     * 如果請求靜態資源

     * 資源將被直接複製給 response

     * <p/>

     * 如果找不到匹配Action 或者靜態資源,則直接跳出

     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;

        HttpServletResponse response = (HttpServletResponse) res;

        ServletContext servletContext = getServletContext();

        String timerKey = "FilterDispatcher_doFilter: ";

        try {

            UtilTimerStack.push(timerKey);

            request = prepareDispatcherAndWrapRequest(request, response);

            ActionMapping mapping;

            try {

                mapping=actionMapper.getMapping(request, dispatcher.getConfigurationManager());

            } catch (Exception ex) {

                LOG.error("error getting ActionMapping", ex);

                dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);

                return;

            }

            if (mapping == null) {

                String resourcePath = RequestUtils.getServletPath(request);

                if ("".equals(resourcePath) && null != request.getPathInfo()) {

                    resourcePath = request.getPathInfo();

                }

                if (serveStatic && resourcePath.startsWith("/struts")) {

                    String name = resourcePath.substring("/struts".length());

                    findStaticResource(name, request, response);

                } else {

                    //為一個普通的request, 則通過

                    chain.doFilter(request, response);

                }

                return;

            }

/**

*這個方法詢問ActionMapper是否需要呼叫某個Action來處理這個(request)請求,

*如果ActionMapper決定需要呼叫某個Action,

*FilterDispatcher則把請求的處理交給ActionProxy

            dispatcher.serviceAction(request, response, servletContext, mapping);

        } finally {

            try {

                ActionContextCleanUp.cleanUp(req);

            } finally {

                UtilTimerStack.pop(timerKey);

            }

        }

}

… …

}

在doFilter()方法中,將呼叫dispatcher.serviceAction,該方法如果找到相應的Action,將把使用者請求交給ActionProxy。serviceAction()程式碼在Dispatcher.java中,如程式碼3.2所示。

程式碼3.2  Dispatcher類

publicclass Dispatcher {

...

/**

     * 為mapping載入類,並呼叫相應的方法或者直接返回result

     * <p/>

     * 根據使用者請求的引數,建立Action上下文

     * 根據指定的Action’名稱和包空間名稱,載入一個Action代理 <tt>ActionProxy</tt> 

     * 然後Action的相應方法將被執行,

     
*/


    
publicvoid serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context, ActionMapping mapping) throws ServletException {

        Map
<String, Object> extraContext = createContextMap(request, response, mapping, context);

        
//如果存在一個值棧,則建立一個新的並複製以備Action使用

        ValueStack stack 
= (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);

        
if (stack!=null{

            extraContext.put(ActionContext.VALUE_STACK, ValueStackFactory.getFactory().createValueStack(stack));

        }


        String timerKey 
="Handling request from Dispatcher";

        
try{

            UtilTimerStack.push(timerKey);

            String namespace 
= mapping.getNamespace();

            String name 
= mapping.getName();

            String method 
= mapping.getMethod();

            Configuration config 
= configurationManager.getConfiguration();

            
//FilterDispatcher把請求的處理交給ActionProxy

            ActionProxy proxy 
= config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, extraContext, truefalse);

            proxy.setMethod(method);

            request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());

            
//ActionMapping 直接返回一個result

            
if (mapping.getResult() !=null{

                Result result 
= mapping.getResult();

                result.execute(proxy.getInvocation());

            }
else{

                proxy.execute();

            }


            
if (stack !=null{

                request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);

            }


        }
catch (ConfigurationException e) {

            LOG.error(
"Could not find action or result", e);

            sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);

        }
catch (Exception e) {

            
thrownew ServletException(e);

        }
finally{

            UtilTimerStack.pop(timerKey);

相關推薦

Struts 2詳細工作流程

 Struts 2框架本身大致可以分為3個部分:核心控制器FilterDispatcher、業務控制器Action和使用者實現的企業業務邏輯元件。 3.1.1  核心控制器FilterDispatcher 核心控制器FilterDispatcher是Struts 2框架的基礎,包含了框架內部的控制

關於MapReduce詳細工作流程,你真的都知道嗎??

毫無疑問,Hadoop 裡面最複雜的是MapReduce,那麼今天咱們就來看看它的整體工作流程: 怎麼樣?是不是懵了? 簡單說下我的理解: 上面的流程是整個 mapreduce 最全工作流程,但是 shuffle 過程只是從第 7 步開始到第16 步結束,具體 shuffle 過程詳

mybaits入門2--mybatis工作流程+實踐練習

上節回顧:上節介紹了mybatis歷史,特點以及環境的搭建,本節主要介紹下mybatis的工作流程以及使用它進行一個簡單的練習 一、mybatis的工作流程 在整個過程中,比較關鍵的是兩個配置檔案,兩個物件,下面我儘量用白話文把過程梳理一遍: 1.SqlSessionF

MapReduce與Yarn 的詳細工作流程分析

MapReduce詳細工作流程之Map階段 如上圖所示 首先有一個200M的待處理檔案 切片:在客戶端提交之前,根據引數配置,進行任務規劃,將檔案按128M每塊進行切片 提交:提交可以提交到本地工作環境或者Yarn工作環境,本地只需要提交切片資訊和xml配置檔案,Yarn環境還需要提交jar包;本地

Struts 2 Spring Hibernate三大框架的執行流程以及原理

freemark 步驟 二維 ring logs spa att spring 添加 轉:http://www.cnblogs.com/System-out-println/p/5974113.html Struts2框架 一、簡介 Struts2是一個相當強大的Ja

CKEditor圖片上傳實現詳細步驟(使用Struts 2)

struts2 none bject parameter found contains 使用 工具 call 本人使用的CKEditor版本是4.7.0 CKEditor的編輯器工具欄中有一項“圖片域”,該工具可以貼上圖片地址來在文本編輯器中加入圖片,但是沒有圖片上傳。

Android4 2 G-Sensor工作流程

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Struts2學習之1(Struts2的工作流程,動作類的編寫,struts.xml配置檔案的編寫)

Struts2的開始 Struts2的作用 現在專案一般都是按照三層架構來開發的,表現層,業務邏輯層,資料訪問層,Struts2就是用來代替servlet處理表現層的一種框架,用來處理頁面的請求跳轉與資料顯示等,Struts2裡面還是用servlet來實

編譯原理學習周入門教程--(2)編譯程式的六個工作流程

上篇我們介紹了什麼是編譯程式,簡單提到了這個“工廠”工作的六個階段。本篇介紹一下這六個階段。 “工廠”導航圖(翻譯工作的過程):      流水線一--詞法分析: 也就是從左到右一個一個的讀入源程

Apache Kafka -2 工作流程

Apache Kafka教程 之 Apache Kafka -工作流程 Apache Kafka - 工作流程 kafka只是一個分為一個或多個分割槽的主題集合。kafka分割槽是線性有序的訊息序列,其中每個訊息由其索引(稱為偏移量)

Struts】- Struts1.3 工作流程

浪費了“黃金五年”的Java程式設計師,還有救嗎? >>>   

Struts 2

str dex 配置信息 動作 業務邏輯 信息 組件 eem 需要   Struts 2是基於MVC模式的Web框架,主要包括控制器組件==>C(包括核心控制器StrutsPrepareAndExecuteFilter、業務控制器Action)、模型組件==>M

Struts2工作流程

根據 系列 div images 實例 ima strong http響應 fig Struts2是一個非常優秀的MVC框架,它主要通過StrutsPrepareAndExecuteFilter過濾器將Struts2集成到Web應用中的。 基本工作流程: 1、客戶端提交一個

一個簡單的時間片輪轉多道程序內核操作系統工作流程

gson star 高級 time author family num 個數 count 一.操作系統工作概述 存儲程序計算機工作模型,計算機系統最最基礎性的邏輯結構; 函數調用堆棧,高級語言得以執行的基礎; 中斷。多道程序操作系統的基點。 二.代

Git手冊 - 工作流程

git如果代碼已經通過測試,那麽則可以采取以下步驟或流程完成代碼的合並:1)切換至master分支,記住千萬別直接提交修改至master分支:#git checkout master2)基於master分支新建個臨時分支,並切換至新建的分支#git checkout -b branchName3)將要提交的代

SpringMVC框架之工作流程

spring 映射 servle 生成 del 視圖解析 http 即將 pan 1、SpringMVC的基本工作流程 2、SpringMVC具體工作流程 1、用戶發送請求至前端控制器DispatcherServlet 2、DispatcherServlet收到請

機器學習工作流程第一步:如何用Python做數據準備?

pandas 整數 情況 意思 編程練習 人工智能 簡單的 準備工作 標題 這篇的內容是一系列針對在Python中從零開始運用機器學習能力工作流的輔導第一部分,覆蓋了從小組開始的算法編程和其他相關工具。最終會成為一套手工制成的機器語言工作包。這次的內容會首先從數據準備開始。

spring+springmvc+mybatis詳細運轉流程

har pop color bits overflow one tom common jdbc spring+springmvc+mybatis詳細運轉流程 2016-04-14 23:38 1892人閱讀 評論(0) 收藏 舉報 分類: SSM

RDIFramework.NET ━ .NET快速信息化系統開發框架 ━ 工作流程組件介紹

質量 可定制 soa 發包 三方 種類 control eight 統計 RDIFramework.NET ━ .NET快速信息化系統開發框架 工作流程組件介紹 RDIFramework.net,基於.NET的快速信息化系統開發、整合框架,給用戶和開發者最佳的.Net框架

struts2的xml配置(struts-2.3.15)

names end action apache .org ctype extends fault default <!-- 約束文件 --> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//D