熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

Struts2的整體流程(上)

2013-11-23 20:06:13  來源: Java開源技術 
    Struts 框架本身大致可以分為個部分核心控制器FilterDispatcher業務控制器Action和用戶實現的企業業務邏輯組件
   
    核心控制器FilterDispatcher
   
    核心控制器 FilterDispatcher是Struts 框架的基礎包含了框架內部的控制流程和處理機制業務控制器Action和業務邏輯組件是需要用戶來自己實現的用戶在開發Action和業務邏輯組件的同時還需要編寫相關的配置文件供核心控制器FilterDispatcher來使用
   
    Struts 的工作流程相對於Struts 要簡單與WebWork框架基本相同所以說Struts 是WebWork的升級版本Struts 框架按照模塊來劃分可以分為Servlet FiltersStruts核心模塊攔截器和用戶實現部分Struts 框架結構圖如圖所示
   

  

 
    圖 Struts 框架結構圖
   
    一個請求在Struts 框架中的處理大概分為以下幾個步驟
   
    客戶端提交一個(HttpServletRequest)請求如上文在浏覽器中輸入
   
    就是提交一個(HttpServletRequest)請求
   
    請求被提交到一系列(主要是層)的過濾器(Filter)如(ActionContextCleanUp其他過濾器(SiteMesh等) FilterDispatcher)注意這裡是有順序的先ActionContext CleanUp再其他過濾器(Othter FiltersSiteMesh等)最後到FilterDispatcher
   
    FilterDispatcher是控制器的核心就是MVC的Struts 實現中控制層(Controller)的核心
   
    FilterDispatcher詢問ActionMapper是否需要調用某個Action來處理這個(HttpServlet Request)請求如果ActionMapper決定需要調用某個ActionFilterDispatcher則把請求的處理交給ActionProxy
   
    ActionProxy通過Configuration Manager(strutsxml)詢問框架的配置文件找到需要調用的Action類例如用戶注冊示例將找到UserReg類
   
    ActionProxy創建一個ActionInvocation實例同時ActionInvocation通過代理模式調用Action但在調用之前ActionInvocation會根據配置加載Action相關的所有Interceptor(攔截器)
   
    一旦Action執行完畢ActionInvocation負責根據strutsxml中的配置找到對應的返回結果result
   
    Struts 的核心控制器是FilterDispatcher個重要的方法destroy()doFilter()和Init()可以在Struts 的下載文件夾中找到源代碼如代碼所示
   
    代碼 核心控制器FilterDispatcher
   
    public class FilterDispatcher implements StrutsStatics Filter {
   
    /**
   
    * 定義一個Log實例
   
    */
   
    private static final Log LOG = LogFactorygetLog(FilterDispatcherclass)
   
    … …
   
    /**
   
    * 存放屬性文件中的STRUTS_IN_ENCODING值
   
    */
   
    private static String encoding;
   
    /**
   
    * 定義ActionMapper實例
   
    */
   
    private static ActionMapper actionMapper;
   
    /**
   
    * 定義FilterConfig實例
   
    */
   
    private FilterConfig filterConfig;
   
    protected Dispatcher dispatcher;
   
    /**
   
    * 創建一個默認的dispatcher初始化filter
   
    * 設置默認的packages     *
   
    */
   
    public void init(FilterConfig filterConfig) throws ServletException {
   
    thisfilterConfig = filterConfig;
   
    dispatcher = createDispatcher(filterConfig)
   
    dispatcherinit()
   
    String param = filterConfiggetInitParameter(packages
   
    String packages = orgapachestrutsstatic template orgapachestrutsinterceptordebugging;
   
    if (param != null) {
   
    packages = param + + packages;
   
    }
   
    thispathPrefixes = parse(packages)
   
    }
   
    //銷毀filter方法
   
    public void destroy() {
   
    if (dispatcher == null) {
   
    LOGwarn(something is seriously wrong Dispatcher is not initialized (null)
   
    } else {
   
    dispatchercleanup()
   
    }
   
    }
   
    /**
   
    * 處理一個Action或者資源請求
   
    *
   
    * filter嘗試將請求同action mapping相匹配
   
    * 如果找到將執行dispatcher的serviceAction方法
   
    * 如果Action處理失敗 doFilter將建立一個異常


   
    *
   
    * 如果請求靜態資源
   
    * 資源將被直接復制給 response
   
    *
   
    * 如果找不到匹配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 {
   
    UtilTimerStackpush(timerKey)
   
    request = prepareDispatcherAndWrapRequest(request response)
   
    ActionMapping mapping;
   
    try {
   
    mapping=actionMappergetMapping(request dispatchergetConfigurationManager())
   
    } catch (Exception ex) {
   
    LOGerror(error getting ActionMapping ex)
   
    dispatchersendError(request response servletContext HttpServletResponseSC_INTERNAL_SERVER_ERROR ex)
   
    return;
   
    }
   
    if (mapping == null) {
   
    String resourcePath = RequestUtilsgetServletPath(request)
   
    if (equals(resourcePath) && null != requestgetPathInfo()) {
   
    resourcePath = requestgetPathInfo()
   
    }
   
    if (serveStatic && resourcePathstartsWith(/struts)) {
   
    String name = resourcePathsubstring(/strutslength())
   
    findStaticResource(name request response)
   
    } else {
   
    //為一個普通的request 則通過
   
    chaindoFilter(request response)
   
    }
   
    return;
   
    }
   
    /**
   
    *這個方法詢問ActionMapper是否需要調用某個Action來處理這個(request)請求
   
    *如果ActionMapper決定需要調用某個Action
   
    *FilterDispatcher則把請求的處理交給ActionProxy
   
    dispatcherserviceAction(request response servletContext mapping)
   
    } finally {
   
    try {
   
    ActionContextCleanUpcleanUp(req)
   
    } finally {
   
    UtilTimerStackpop(timerKey)
   
    }
   
    }
   
    }
   
    … …
   
    }
   
    在doFilter()方法中將調用dispatcherserviceAction該方法如果找到相應的Action將把用戶請求交給ActionProxyserviceAction()代碼在Dispatcherjava中如代碼所示
   
    代碼 Dispatcher類
   
    public class Dispatcher {
   
    …
   
    /**
   
    * 為mapping加載類並調用相應的方法或者直接返回result
   
    *
   
    * 根據用戶請求的參數建立Action上下文
   
    * 根據指定的Action名稱和包空間名稱加載一個Action代理 ActionProxy
   
    * 然後Action的相應方法將被執行
   
    */
   
    public void serviceAction(HttpServletRequest request HttpServletResponse response ServletContext context ActionMapping mapping) throws ServletException {
   
    Map extraContext = createContextMap(request response mapping context)
   
    //如果存在一個值棧則建立一個新的並復制以備Action使用
   
    ValueStack stack = (ValueStack) requestgetAttribute(ServletActionContextSTRUTS_VALUESTACK_KEY)
   
    if (stack!= null) {
   
    extraContextput(ActionContextVALUE_STACK ValueStackFactorygetFactory()createValueStack(stack))
   
    }
   
    String timerKey = Handling request from Dispatcher;
   
    try {
   
    UtilTimerStackpush(timerKey)
   
    String namespace = mappinggetNamespace()
   
    String name = mappinggetName()
   
    String method = mappinggetMethod()
   
    Configuration config = configurationManagergetConfiguration()
   
    //FilterDispatcher把請求的處理交給ActionProxy
   
    ActionProxy proxy = configgetContainer()getInstance(ActionProxyFactoryclass)createActionProxy(namespace name extraContext true false)
   
    proxysetMethod(method)
   
    requestsetAttribute(ServletActionContextSTRUTS_VALUESTACK_KEY proxygetInvocation()getStack())
   
    //ActionMapping 直接返回一個result
   
    if (mappinggetResult() != null) {
   
    Result result = mappinggetResult()
   
    resultexecute(proxygetInvocation())
   
    } else {
   
    proxyexecute()
   
    }
   
    if (stack != null) {
   
    requestsetAttribute(ServletActionContextSTRUTS_VALUESTACK_KEY stack)
   
    }
   
    } catch (ConfigurationException e) {
   
    LOGerror(Could not find action or result e)
   
    sendError(request response context HttpServletResponseSC_NOT_FOUND e)
   
    } catch (Exception e) {
   
    throw new ServletException(e)
   
    } finally {
   
    UtilTimerStackpop(timerKey)
   
    }
   
    }
   
    …
   
    }
   
    從上面代碼中可以看出來Struts 用於處理用戶請求的Action實例並不是用戶實現的業務控制器而是Action代理關於Action代理相關內容讀者可以參考攔截器章節的介紹


From:http://tw.wingwit.com/Article/program/Java/ky/201311/27932.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.