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

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

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

    Vincent

    Vicent's blog
    隨筆 - 74, 文章 - 0, 評論 - 5, 引用 - 0
    數據加載中……

    WebWork教程-ServletDispatcher

    ServletDispatcher 是默認的處理 Web Http 請求的調度器,它是一個 JavaServlet ,是 WebWork 框架的控制器。所有對 Action 調用的請求都將通過這個 ServletDispatcher 調度。它將在 web.xml 里配置 ServletDispatcher 時指定,讓所有對 WebWork Action( 默認的是 .action 的后綴 ) 的請求都對應到該調度的 JavaServlet 中,具體配置在前面的 WebWork-helloWorld 中有介紹。
    ?
    ServletDispatcher 接受客戶端的 HTTP 請求,將 JavaServlet 的很多相關對象進行包裝,再傳給我們的 XWork 框架,由我們的 XWork 框架去解析我們的 xwork.xml 配置文件,根據配置文件的信息,創建對應的 Action ,組裝并調用相應的攔截器,執行 Action ,返回執行結果。 WebWork 使用 XWork 的核心,主要是由這個 ServletDispatcher 去實現的
    ?
    具體調用流程: (Servlet 調用流程 )
    ?
    一、? init ()方法在 web 服務器啟動時調用。
    1 、初始化 Velocity 引擎
    ?
    2 、檢查是否支持配置文件重新載入功能。如果 webwork.configuration.xml.reload (見 webwork.properties 文件)設置為 true, 每個 request 請求都將重新裝載 xwork.xml 配置文件。在開發環境使用將會非常方便,但在生產環境必需設置為 false
    代碼如下:
    if ("true".equalsIgnoreCase(Configuration.getString("webwork.configuration.xml.reload"))) {FileManager.setReloadingConfigs(true);}
    ?
    3 、設置一些文件上傳的信息,比如:上傳臨時目錄,上傳的最大字節等。都設置在 webwork.properties 文件里,如果在 classpath 中找不到這個屬性文件,它會去讀取默認的 default.properties
    ?
    二、?? service ()方法,每次客戶端的請求都將調用此方法
    1、??????????? 通過 request 請求取得 action 的命名空間( namespace ,與 xwork.xml 配置文件里 package 標簽的 name 對應)
    例如: /foo/bar/MyAction.action ,取得的命名空間為 /foo/bar xwork.xml 配置文件里應該有這一段: <package name="foo.bar" …….
    ?
    2、??????????? 根據 servlet 請求的 Path, 解析出要調用該請求的 Action 的名字( actionName ),例如:( ../foo/bar/MyAction.action -> MyAction
    xwork.xml 配置文件里應該有:
    <package name="foo.bar" …….
    <Action name=” MyAction”……]
    ?
    3、??????????? 創建 Action 上下文( extraContext )。我們前面介紹的 ActionContext 上下文的對象,就是在這里設置的。它將 JavaServlet 相關的對象進行包裝,放入到 extraContext 這個 Map 對象里。
    /**
    ???? * 將所有的應用請求和 servlet 屬性保存到一個 HashMap 中,
    ???? * @param requestMap 存放所有 request 請求屬性的 Map
    ???? * @param parameterMap 存放所有 request 請求參數的 Map
    ???? * @param sessionMap 存放所有 session 屬性的 Map
    ???? * @param applicationMap 存放所有 servlet 上下文屬性的 Map
    ???? * @param request?HttpServletRequest 對象
    ???? * @param response ?HttpServletResponse 對象 .
    ???? * @param servletConfig ?ServletConfig 對象 .
    ???? * @return 代表 Action 上下文的一個 HashMap
    */
    ?
    ?
    public static HashMap createContextMap(Map requestMap, Map parameterMap, Map sessionMap, Map applicationMap, HttpServletRequest request, HttpServletResponse response, ServletConfig servletConfig) {
    ??????? HashMap extraContext = new HashMap();
    ??????? extraContext.put(ActionContext.PARAMETERS, parameterMap);
    ??????? extraContext.put(ActionContext.SESSION, sessionMap);
    ??????? extraContext.put(ActionContext.APPLICATION, applicationMap);
    ??????? extraContext.put(ActionContext.LOCALE, request.getLocale());
    ?
    ??????? extraContext.put(HTTP_REQUEST, request);
    ??????? extraContext.put(HTTP_RESPONSE, response);
    ??????? extraContext.put(SERVLET_CONFIG, servletConfig);
    ??????? extraContext.put(COMPONENT_MANAGER, request.getAttribute("DefaultComponentManager"));
    ?
    ??????? // helpers to get access to request/session/application scope
    ??????? extraContext.put("request", requestMap);
    ??????? extraContext.put("session", sessionMap);
    ??????? extraContext.put("application", applicationMap);
    ??????? extraContext.put("parameters", parameterMap);
    ?
    ??????? AttributeMap attrMap = new AttributeMap(extraContext);
    ??????? extraContext.put("attr", attrMap);
    ?
    ??????? return extraContext;}
    下面我們來看看它是如何將 request 請求的參數和 session 進行包裝的:
    Request 包裝
    protected Map getParameterMap(HttpServletRequest request) throws IOException {
    ??????? return request.getParameterMap();
    }
    這個方法比較簡單,它直接調用了 HttpServletRequest 的方法 getParameterMap (),將所有 request 請求的參數封裝到一個 Map
    ?
    Session 包裝
    protected Map getSessionMap(HttpServletRequest request) {
    ??????? return new SessionMap(request);
    }
    這個方法取得所有 Session 中的屬性,它調用了 com.opensymphony.webwork.dispatcher. SessionMap 類,這個類實現了 Map 接口,在 entrySet ()方法中列舉 Session 的所有屬性,存放在 Set 中。
    ?
    4、??????????? 根據前面獲得的 namespace actionName extraContext ,創建一個 ActonProxy
    ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, actionName, extraContext);
    默認的 proxy com.opensymphony.xwork.DefaultActionProxy ,在它的構造函數會進行下面的操作:
    1 )、根據 namespace actionName 讀取 xwork.xml 配置文件里這個 Action 的所有配置信息
    ?
    2 )、創建 ActionInvocation
    invocation=ActionProxyFactory.getFactory().createActionInvocation(this, extraContext); 默認的 invocation com.opensymphony.xwork.DefaultActionInvocation ,它的構造函數操作有 :
    ?
    ???????????????????????? i.????????????? com.opensymphony.xwork.ObjectFactory 創建我們配置文件描述的 Action 對象。再將這個 Action 對象存放入 OgnlValueStack 中。記得我們前面用戶注冊的例子嗎?當用戶提交表達時它會有表達式語言向 OgnlValueStack 取得 Action 對象的字段,再把輸入框的數據設置到對應的 Action 字段中,這個 Action 對象就是在這個時候進棧的

    ??????????????????????? ii.????????????? 傳入 extraContext 參數,創建與 ActionInvocation 對應的 Action 上下文( ActionContext )。記得我們在介紹 ActionContext 的最后,提出了一個需要注意的地方:不要在 Action 構造函數中調用 ActionContext.getContext() 。現在應該能明白,原來是 Action 對象實例在 ActionContext 對象實例之前創建的,所有這樣取得 ActionContext 容器對象就有可能會返回 null

    ????????????????????? iii.????????????? 取得這個 Action 對應的所有攔截器( Interceptor ),存放入 java.util.Iterator 對象中。
    ?
    5、??????????? 執行 proxy execute() 方法,這個方法最核心的語句是: retCode = invocation.invoke(); invocation 對象的 invoke() 方法它遍歷并執行這個 Action 對應的所有攔截器,執行 Action 對應的方法(默認的是 execute() ),根據 Action 執行返回的值去調用執行相應的 Result (返回結果處理)的方法
    ?
    Action 的單元測試
    理解了 ServletDispatcher ,我們就明白了整個框架調用執行的順序。 Action 雖然是與 Web 無關,可是它的創建、參數設置、執行與我們的 WebWork XWork 緊密關聯在一起,有我們的控制器 ServletDispatcher 去統一調度,那我們如何去對 Action 進行獨立的單元測試呢?
    請看下面的例子:使用單元測試框架 JUnit register.User. RegisterAction 做單元測試
    example.register. RegisterActionTest testExecuteWithProxyFactory() 方法
    ?
    public void testExecuteWithProxyFactory() throws Exception{
    ???????
    ??????? // 創建 action 上下文( actionContext
    ??????? Map params = new HashMap();
    ??????? params.put("user.username","Moxie");
    ??????? params.put("user.password","mypassword");
    ??????? params.put("user.email","achqian@yahoo.com.cn");
    ??????? params.put("user.age",new Integer(23));
    ??????? Map extraContext = new HashMap();
    ??????? extraContext.put(ActionContext.PARAMETERS,params);
    ???????
    ??????? // 創建代理(找出所在的 action
    ??????? ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy("example", "register", extraContext);
    ?
    ??????? // 不要執行出現 Success 后的代碼
    proxy.setExecuteResult(false);
    ???????
    ??????? // 測試代碼是否正確
    ??? ??? assertEquals(proxy.execute(),"success");
    ???????
    ??????? // 返回 Action ,測試 action 里面的代碼是否正確
    ??????? RegisterAction action = (RegisterAction) proxy.getAction();
    ??????? assertEquals(action.getUser().getUsername(),"Moxie");
    ??????? assertEquals(action.getUser().getAge(),23);
    ??? }
    ?
    下面解說這個方法:
    1、?? 對象 params 表示請求參數的 Map, 在它里面設置了注冊用戶的信息。 extraContext 當然就是我們 ActionContext 上下文的容器,它里面保存了放置請求參數的對象 params
    2、?? 創建我們的 ActionProxy ,它傳入的參數有:“ example ”-這個 Action 的命名空間,“ register ”- Action 對應的名字, extraContext -存放 Actin 上下文里的對象,,執行并將它返回的值與“ success ”比較,測試 Action 是否能正確執行完成。注意: proxy.setExecuteResult(false); ,因為我們是單元測試,所以 Action 執行完成就可以了,不用再去調用結果響應的操作,故將是否執行結果設置為“ false ”。
    3、?? Action 正確執行完成之后,我們也可以測試現在 Action 的字段里的數據是否按照我們預期的要求正確設置。從 ActionProxy 對象里取得執行的 Action ,即 RegisterAction 對象,再取得它的 User 模型,將其數據與前面設置參數的數據進行比較,判斷它是否等于我們預期設置的數值。
    ?
    ?
    Result Type
    前面我們學習了 ServletDispatcher ,它是 WebWork 框架機制的核心。它和 Action 在我們 MVC 模式中,扮演著控制器的角色, MVC 模式通過控制器實現了我們模型和視圖的分離。 WebWork 提供了多種活靈活視圖展現方式。
    我們先看看前面用戶注冊例子的展現方式:我們使用的是 Jsp WebWork 自帶的標簽庫, Action 對應的視圖當然是在 xwork.xml 配置文件里設置:
    <action name="register" class="example.register.RegisterAction" >
    <result name="success" type="dispatcher">
    ?????????? <param name="location">register-result.jsp</param>
    </result>
    <interceptor-ref name="params"/>
    </action>
    ?
    Result Action 執行完返回的一個字符串常量,它表示 Action 執行完成的狀態,比如:執行成功、執行失敗等。在我們前面 Action 的介紹中,詳細介紹了它默認的標準 Result ,當然 Result 我們也可以自己定義,只要是一個字符串常量就可以了。
    ?
    Result 的值在 xwork.xml 配置文件里就是 result 標簽里“ name ”的值, name="success" 表示 Action 執行成功,返回“ success ”就對應此標簽的配置,進行視圖輸出:
    type ”就是我們的 Result Type Result Type 是一個類,它在 Action 執行完成并返回 Result 之后,決定采用哪一種視圖技術,將執行結果展現給用戶。我們輸出的類型是
    type="dispatcher" ,它對應 com.opensymphony.webwork.dispatcher.ServletDispatcherResult 這個類,它將執行結果通過 javax.servlet.RequestDispatcher forward() include() 方法調度到 Jsp 頁面展現。
    我們可以自己開發 Result Type ,實現我們需要的視圖展現方式。 Result Type 必需要實現 com.opensymphony.xwork..Result 接口。在 WebWork 中,它已經為我們提供了很多 Result Type ,實現了視圖部分對 JSP, Velocity, FreeMarker, JasperReports XML 等的支持,具體如下表格 :
    Result Type
    Nname
    Class
    Dispatcher
    dispatcher
    com.opensymphony.webwork.dispatcher.ServletDispatcherResult
    Redirect
    Redirect
    com.opensymphony.webwork.dispatcher.ServletRedirectResult
    Action Chaining
    Chain
    com.opensymphony.xwork.ActionChainResult
    Velocity
    Velocity
    com.opensymphony.webwork.dispatcher.VelocityResult
    FreeMarker
    freemarker
    com.opensymphony.webwork.views.freemarker.FreemarkerResult
    JasperReports
    Jasper
    com.opensymphony.webwork.views.jasperreports.JasperReportsResult
    XML/XSL
    Xslt
    com.opensymphony.webwork.views.xslt.XSLTResult
    HttpHeader
    ?
    com.opensymphony.webwork.dispatcher.HttpHeaderResult
    ?
    ?
    Dispatcher 通過 javax.servlet.RequestDispatcher forward() include() 方法調度到頁面展現,這樣的頁面一般是 Jsp 頁面。
    ?
    參數 (Parameters)
    是否必需
    ?
    location
    執行完成之后轉向的位置
    parse
    默認的是“ true ”,如果設置為“ false ”, location 參數將不會被 OGNL 表達式語言解析
    例子:
    <result name="success" type="dispatcher">
    ?????????? <param name="location">register-result.jsp</param>
    ???????? </result>
    也可以簡單寫成這樣:
    ?? <result name="success" type="dispatcher">register-result.jsp</result>
    ?
    ?
    Action Chaining 一種特殊的視圖結果,將 Action 執行完之后鏈接到另一個 Action 中繼續執行。新的 Action 使用上一個 Action 的上下文( ActionContext )。
    ?
    參數 (Parameters)
    是否必需
    ?
    actionName
    將要被鏈接的 Action 名字
    namespace
    被鏈接的 Action 的命名空間( namespace ),如果不設置,默認的即是當前的命名空間
    例子:
    <result name="success" type="chain">
    ??? <param name="actionName">bar</param>
    ??? <param name="namespace">/foo</param>
    </result>
    ?
    將要調用的 Action 如下:
    <action name="bar" class="myPackage.barAction">
    ??? ...
    </action>
    ?
    Velocity 它類似 Jsp 的執行環境(使用 JavaServlet 容器),將 Velocity 模板轉化成數據流的形式,直接通過 JavaServlet 輸出。
    ?
    參數 (Parameters)
    是否必需
    ?
    location
    執行完成之后轉向的位置 ( 一般是 .vm 頁面 )
    parse
    默認的是“ true ”,如果設置為“ false ”, location 參數將不會被 OGNL 表達式語言解析
    例子:
    <result name="success" type="velocity">
    ??? <param name="location">foo.vm</param>
    </result>
    ?
    ?
    FreeMarker FreeMarker 是一個純 Java 模板引擎;一個普通的基于模板生成文本的工具,它只能應用在 Web 應用環境中。
    ?
    參數 (Parameters)
    是否必需
    ?
    location
    執行完成之后轉向的位置
    parse
    默認的是“ true ”,如果設置為“ false ”, location 參數將不會被 OGNL 表達式語言解析
    contentType
    如果不指定,默認的是 "text/html"
    例子:
    <result name="success" type="freemarker">foo.ftl</result>
    ?
    ?
    JasperReports Action 執行的結果通過 JasperReports 報表形式輸出,可以指定 JasperReports 支持的輸出格式( PDF HTML XLS CSV XML 等),默認是通過 PDF 格式輸出。
    參數 (Parameters)
    是否必需
    ?
    location
    執行完成之后轉向的位置
    parse
    默認的是“ true ”,如果設置為“ false ”, location 參數將不會被 OGNL 表達式語言解析
    dataSource
    它是 Action 的一個字段(通常是一個 List ), OGNL 表達式被用來去 value stack OgnlValueStack )重新找回這個 dataSource
    format
    報表生成的數據格式,默認的是 pdf
    例子:
    <result name="success" type="jasper">
    ??? <param name="location">foo.jasper</param>
    ??? <param name="dataSource">mySource</param>
    ??? <param name="format">CSV</param>
    </result>
    ?
    或者默認的 pdf 格式
    <result name="success" type="jasper">
    ??? <param name="location">foo.jasper</param>
    ??? <param name="dataSource">mySource</param>
    </result>
    ????????
    XML/XSL 將結果轉換為 xml 輸出
    ?
    參數 (Parameters)
    是否必需
    ?
    location
    執行完成之后轉向的位置
    parse
    默認的是“ true ”,如果設置為“ false ”, location 參數將不會被 OGNL 表達式語言解析
    例子:
    <result name="success" type="xslt">foo.xslt</result>??

    posted on 2006-09-01 13:41 Binary 閱讀(651) 評論(0)  編輯  收藏 所屬分類: Webwork

    主站蜘蛛池模板: 免费人成激情视频| 亚洲人成电影在线播放| 亚洲av无码无线在线观看 | 亚洲国产精品人人做人人爽| 精品无码一级毛片免费视频观看 | 国产av无码专区亚洲av毛片搜| 亚洲日本一区二区三区在线| 免费视频爱爱太爽了| 国产成人亚洲精品播放器下载| 亚洲国产精品无码专区影院| 大陆一级毛片免费视频观看| 国产一级在线免费观看| 久久亚洲国产最新网站| 亚洲精品二区国产综合野狼| 免费无码AV电影在线观看| 视频免费在线观看| 亚洲日本成本人观看| 亚洲av女电影网| 四虎免费影院4hu永久免费| 一区二区免费视频| 夜夜爽妓女8888视频免费观看| 亚洲成人福利网站| 在线观看亚洲成人| 蜜臀91精品国产免费观看| 久久午夜伦鲁片免费无码 | 在线观看免费污视频| 精品免费视在线观看| 国产AV无码专区亚洲AV麻豆丫 | 国产免费AV片在线观看播放| 在线综合亚洲欧洲综合网站| 亚洲AV无码专区国产乱码电影| 免费h成人黄漫画嘿咻破解版| 黄色成人免费网站| 特级精品毛片免费观看| jyzzjyzz国产免费观看| 亚洲AV日韩AV一区二区三曲| 亚洲一卡二卡三卡| 亚洲黄色免费网站| 亚洲a在线视频视频| 亚洲人成网站在线观看播放| 亚洲欧洲自拍拍偷精品 美利坚|