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

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

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

    Starting Struts2--Core Components(3)

    Posted on 2007-08-09 17:05 puras 閱讀(1306) 評論(3)  編輯  收藏 所屬分類: Struts2.0

    Result Types

    從action生成結(jié)果,并返回組用戶不同的結(jié)果值,不都需要相同的類型.結(jié)果"success"可以渲染為一JSP頁面,但結(jié)果"error"可能需要發(fā)送一個HTTP頭返回給瀏覽器.

    結(jié)果的類型使用"type"屬性在結(jié)果節(jié)點配置.與"name"屬性相似,這個屬性也有一個默認值-"dispatcher"-將渲染JSPs.大多數(shù)的時間,你將使用所提供的結(jié)果類型,但有時也可能提供自定義的實現(xiàn).

    Request and Form Data

    為了要做出Action應(yīng)該如何工作的決定,并且提供數(shù)據(jù)的數(shù)據(jù)庫持久對象,Action可能需要從請求字符串中訪問值,并生成數(shù)據(jù).

    Struts2沿序JavaBean的方式-如果你想訪問數(shù)據(jù),你需要為字段提供一個getter和setter方法.訪問請求字符串和form里的值是一樣的.每個請求字符串或是Form里的值都是一個簡單的名值對,所以為一個特定的名稱賦值,需在action里創(chuàng)建一個setter方法.例如,如果JSP發(fā)起了一個請求,"/home.action?framework=struts&version=2",Action需要提供setter方法"setFramework(String frameworkname)",和setter方法"setVersion(int version)".

    注意在這個例子中,setter方法不是一定需要一個String的值.默認的,Struts2將從一個String轉(zhuǎn)換成action所需的類型.可以轉(zhuǎn)換所有的原始類型和基礎(chǔ)對象類型,而且可以配置你自己的自定義類.Struts2同樣可以操作復(fù)雜對象中的值,例如,一個名稱在Form元素中稱為"person.address.home.postcode",值為"2",Struts2將使用同樣的調(diào)用方式"getPerson().getAddress().getHome().setPostcode(2)".

    Accessing Business Services

    到現(xiàn)在為止,我們都在討論如果配置action,如果控制渲染不同的結(jié)果返回給用戶.對于action是做什么的,是非常重要的一部分,但是,返回它們的結(jié)果之前,一些處理需要執(zhí)行.對于這個,它們需要訪問一些不同類型的對象-商業(yè)對象,數(shù)據(jù)訪問對象,或是其他資源.

    為了提供一個松耦合的系統(tǒng),Struts2使用稱為依賴注入或是控制反轉(zhuǎn)(IOC)的技術(shù).依賴注入可以通過構(gòu)造函數(shù)注入,接口注入和set方法注入來實現(xiàn).Struts2使用set方法注入.意思是對于action可用的對象,你僅需要提供一個setter.首選的依賴注入框架是Spring框架,可以通過插件配置進來.另一個選擇是Plexus,或都如果你喜歡,你可以替換成你自己的實現(xiàn).

    也有一些對象不能用Spring框架管理,比如像HttpServletRequest.這些對象是組合使用setter注入和接口注入來操作.對于每一個非商業(yè)對象,都有個相應(yīng)的口(大家都知道的"aware"接口),Action必須實現(xiàn)這個接口.

    注:
    WebWork最初有自己的依賴注入框架.它在2.2版時,刪除了這個特征,而改用Spring框架替換.最初的組件框架是基于接口的,所以為每個組件接口和接口的實現(xiàn)類,都需要提供.

    另外,每個組件都有一個"Aware"接口,為組件提供一個setter.如果接口是"UserDAO",那么Aware接口則為"UserDAOAware"(約定俗成),并且擁有一個方法-一個setter,"void setUserDAO(UserDAO dao);".

    攔截器會為必要的接口和setters注入必要的對象注入.

    Accessing Data from the Action

    有些時候,需要查看被action修改過的對象.有幾種技術(shù)可以被使用.

    很多WEB程序員熟悉的技術(shù)是將需要訪問的對象放到HttpServletRequest和HttpSession中.這可以通過實現(xiàn)"aware"接口來完成,然后設(shè)置對像,使用特定的名稱訪問.

    如果你想使用內(nèi)建的標(biāo)簽或是引入JSTL支持,訪問數(shù)據(jù)就非常容易了.他們兩個都可以通過值棧直接存取action.唯一的工作就是程序員需要給Action里允許被訪問的需要存取的對象提供getter方法.

    我們將在后面的部分更詳細的討論值棧.

    Interceptors

    Struts2框架使用攔截器提供了許多特征;例如包含異常處理,文件上傳,生命周期回調(diào)和驗證.攔截器是同Servlet過濾器或是JDKs的代理類相同的概念.它們提供了Action的前處理和后處理的方法.與Servlet過濾器相似,攔截器也可以分層和排序.They have access to the action being executed, as well as all environmental variables and execution properties.

    讓我們開始討論攔截器依賴注入.依賴注入到action當(dāng)中,與我們之前看到的一樣,有兩種不同的形式出現(xiàn).有一些攔截器是我們已經(jīng)提過的:

    Spring框架-ActionAutowiringInterceptor攔截器
    請求字符串和Form值-ParametersInterceptor攔截器
    Servlet基礎(chǔ)對象-ServletConfigInterceptor

    前兩個攔截器獨立工作,不需要Action再做什么,但最后一個卻是不同的.它同下面的接口協(xié)作工作:

    SessionAware-通過一個Map來提供對所有Session屬性的訪問
    ServletRequestAware-提供對HttpServletRequest對象的訪問
    RequestAware-通過一個Map來提供對所有Request屬性的訪問
    ApplicationAware-通過一個Map來提供對所有Application屬性的訪問
    ServletResponseAware-提供對ServletResponse對象的訪問
    ParameterAware-通過一個Map來提供對所有請求字符串和Form值的訪問
    PrincipalAware-提供對PrincipleProxy對象的訪問;這個對象實現(xiàn)了HttpServletRequest對象的規(guī)則和角色的方法, 但提供個代理,允許獨立于Action的實現(xiàn)
    ServletContextAware-提供對ServletContext對象的訪問

    為了將正確的數(shù)據(jù)注入到Action當(dāng)中,它需要實現(xiàn)必需的接口.

    Configuration

    如果我們想要能夠注入(或任何其他由攔截器提供的功能)到我們的Action,我們需要提供配置.像其他元素一樣,大多數(shù)的攔截器已經(jīng)為你配置好了.只需要你的Actions的包繼承自"struts-default"包即可.

    要配置一個新的攔截器,我們首先需要定義這個攔截器.將<interceptors … />和<interceptor …/>標(biāo)簽直屬<package>標(biāo)簽.對于上面提到的Spring框架攔截器,它的配置如下:

     

    1<interceptors>
    2    …
    3    <interceptor name="autowiring"
    4        class="interceptor.ActionAutowiringInterceptor"/>
    5</interceptors>

     

    我們同樣需要確認將攔截器應(yīng)用到需要它的Action上.這可以通過兩種方法實現(xiàn).第一種是將攔截器分配給每個Action:

     

    1<action name="my" class="com.fdar.infoq.MyAction" >
    2    <result>view.jsp</result>
    3    <interceptor-ref name="autowiring"/>
    4</action>

     

    使用這種配置,可以被應(yīng)用到Action上的攔截器沒有數(shù)量的限制.現(xiàn)在所需要的就是排列攔截器的順序,它們都將被執(zhí)行.

    第二種方式是為當(dāng)前的包分配默認的攔截器:

    <default-interceptor-ref name="autowiring"/>


    這個定義是直屬<package ... />標(biāo)簽 的,并且只能有一個攔截器被定義成默認的.

    現(xiàn)在已將攔截器配置到了Action映射上了,它將在每個映射的URL請求時被執(zhí)行.但是這樣有一些限制,更多的時候,我們需要將多個攔截器指派給一個Action.事實上,Struts2里基礎(chǔ)的功能攔截器有很多,給每個Action指派7,8個攔截器也不是不可能的事.你可以假設(shè)一下,為每個Action配置各個攔截器,很快就會變得極難管理.因為這個原因,可使用攔截器棧來管理攔截器.這里有個例子,來自struts-default.xml文件:

     

    1<interceptor-stack name="basicStack">
    2    <interceptor-ref name="exception"/>
    3    <interceptor-ref name="servlet-config"/>
    4    <interceptor-ref name="prepare"/>
    5    <interceptor-ref name="checkbox"/>
    6    <interceptor-ref name="params"/>
    7    <interceptor-ref name="conversionError"/>
    8</interceptor-stack>

     

    這個配置節(jié)點在<package ... />節(jié)點之下.每個<interceptor-ref … />標(biāo)簽引用一個攔截器或是一個在當(dāng)前攔截器棧之前定義的攔截器棧.

    我們已經(jīng)看過如何將攔截器應(yīng)用于Action之上,應(yīng)用攔截器棧沒有什么不同.事實上,我們正是使用相同的標(biāo)簽:

     

    1<action name="my" class="com.fdar.infoq.MyAction" >
    2    <result>view.jsp</result>
    3    <interceptor-ref name="basicStack"/>
    4</action>

     

    這種做法對于默認的攔截器同樣有效-簡單的使用一個攔截器棧要優(yōu)于使用單個的攔截器.

    <default-interceptor-ref name="basicStack"/>


    所以在配置實始攔截器和攔截器棧的時候,保證配置所有的攔截器和攔截器棧的名稱唯一是非常重要的.

    Implementing Interceptors

    在你的應(yīng)用中使用自定義的攔截器為應(yīng)用提供cross-cutting特征是一個非常好的方式.只需要實現(xiàn)來自XWork框架的一個簡單的接口.它只有3個方法:

     

    1public interface Interceptor extends Serializable {
    2    void destroy();
    3    void init();
    4    String intercept(ActionInvocation invocation) throws Exception;
    5}

     

    事實上,如果實始化和清除方法不是必需的,可以替代成擴展AbstractInterceptor類.這個類為"destroy"和"init"方法提供了默認的空實現(xiàn).

    ActionInvocation對象提供了對運行環(huán)境的訪問.它允許訪問Action本身,context(對于一個WEB應(yīng)用,包含請求參數(shù),session參數(shù)等),action執(zhí)行的結(jié)果和調(diào)用action的方法,并確定action是否已經(jīng)被調(diào)用.

    我們已經(jīng)知道如何來配置攔截器了,配置自定義攔截的方式完全相同.如果你創(chuàng)建了你自己的攔截器,你將同樣會考慮創(chuàng)建自定義的攔截器棧.這樣你將確認你的應(yīng)用保持一致,新的攔截器可以處理所有需要他的actions.

    Value Stack / OGNL

    這個部分包括相關(guān)緊密地的二個概念.值棧正確的說應(yīng)該是棧對象.OGNL則是Object Graph Navigational Language的縮寫,提供在值棧里標(biāo)準的訪問對象的方式.

    值棧由下面羅列的對像組成:
    1.Temporary Objects-在執(zhí)行期間創(chuàng)建臨時對象,并將其放入值棧;一個例子是將當(dāng)前集合中迭代的值循環(huán)的放到JSP標(biāo)簽中
    2.The Model Object-如果模型對象正在使用,那么當(dāng)前模型在action之前放入值棧
    3.The Action Object-正在被執(zhí)行的Action
    4.Named Objects-這些對象包括#application,#session,#request,#attr和#parameters還有相應(yīng)的Servlet范圍

    訪問值棧可以通過許多不同的方式完成.大多數(shù)常用的方式是通過JSP提供的標(biāo)簽,Velocity和Freemarker.HTML標(biāo)簽一般被用于訪問值棧中對象的屬性;控制標(biāo)簽(像if, elseif和iterator)用于表達式;數(shù)據(jù)標(biāo)簽可以操作棧本身(通過set和push).

    在使用值棧的時候,不需要知道目標(biāo)對象存在于哪個范圍之內(nèi).如果你想取屬性"name"的值,你可以向值棧查詢這個屬性.每個棧元素,按照提供的順序,被詢問它是否存在property.如果存在,則返回這個值.如果不存在,則下一個元素會被查詢.這將繼續(xù)一直到棧里的元素全被查詢.這是一個非常好的特征,你不需要知道這個值是哪里的-action,model或是HTTP請求-你只需要知道如果這個值存在,它就將被返回.

    這是downside.如果property是常用的(例如"id"),而且你想從特定的對象(比方說action)取值,也就是說不是值棧中第一個遇到這個property的對象,返回的值可能與你的預(yù)期值不同.想要返回一個"id"的值,但它可能來自于JSP標(biāo)簽,臨時對象,或是來自模型對象.OGNL正好有一種訪問對象的屬性的方法,我們可以在這里使用對我們有利的.如果我們知道棧在action中的深度,我們可以使用"[2].id"來替換"id".

    事實上,OGNL是一種非常有特色的表達式語言.使用圓點符號對對象進行導(dǎo)航(例如,使用表達式"person.address"來替代"getPerson().getAddress()"),OGNL支持的特征如類型轉(zhuǎn)換,方法調(diào)用,集合的處理和創(chuàng)建,projection across ollections,表達式賦值和lambda表達式.完整的語言指南可以查看http://www.ognl.org/2.6.9/Documentation/html/LanguageGuide/index.html.

    Result Types

    到目前為止,我們只展示了配置Action的結(jié)果通過JSP渲染呈遞給用戶.這是一個方案,但卻不是唯一的.事實上,Struts2支持多種類型的結(jié)果.它們可以是可視的,或是可以與環(huán)境交互.

    為action執(zhí)行的結(jié)果配置一個指定的類型,將使用"type"屬性.如果沒有應(yīng)用這個屬性,默認的"dispatcher"類型將被使用-這將呈遞一個JSP的結(jié)果.如何配置action看起來像下面這樣:

     

    1<action name="my" class="com.fdar.infoq.MyAction" >
    2    <result type="dispatcher">view.jsp</result>
    3</action>

     

    Configuration

    結(jié)果類型配置在<package ... />標(biāo)簽內(nèi).這個配置與攔截器的配置相似.一個"name"屬性提供了一個結(jié)果類型的唯一標(biāo)識,并且"class"標(biāo)簽提供實現(xiàn)類.這還有第三個屬性"default"-這允許修改默認的結(jié)果類型.如果一個WEB應(yīng)用基于Velocity而不是JSP,修改默認的將比輸入配置信息省時.

     

    1<result-types>
    2    <result-type name="dispatcher" default="true"
    3        class="….dispatcher.ServletDispatcherResult"/>
    4    <result-type name="redirect"
    5        class="….dispatcher.ServletRedirectResult"/>
    6    …
    7</result-types>

     

    Implementing Result Types

    與攔截器相似,它可能創(chuàng)建出你自己的結(jié)果類型并將它們配置到你的WEB應(yīng)用中.一些常用的結(jié)果類型已經(jīng)存在,所以,在你創(chuàng)建自己的之前,你應(yīng)該先看看你想創(chuàng)建的類型是否已經(jīng)存在.

    為了創(chuàng)建一個新的結(jié)果類型,實現(xiàn)Result接口即可.

    1public interface Result extends Serializable {
    2    public void execute(ActionInvocation invocation) throws Exception;
    3}

     

    ActionInvocation對象提供了對運行環(huán)境的訪問,允許一個新的結(jié)果類型訪問來自剛剛運行的action的信息,也可以訪問執(zhí)行action的上下文.上下文包括了HttpServletRequest對象,可提供對當(dāng)前請求的輸出流的訪問.

    上一章:Starting Struts2--Core Components(2)
    下一章:Starting Struts2--Core Components(4)

    PS:唉,進度很慢,第三章還沒有結(jié)束,不過還好,還差一小部分就能結(jié)束了

    Feedback

    # re: Starting Struts2--Core Components(3)  回復(fù)  更多評論   

    2007-08-10 08:30 by icc
    不錯,多謝!!

    # re: Starting Struts2--Core Components(3)  回復(fù)  更多評論   

    2007-08-10 09:54 by paul
    struts2也支持xwork的model driven的寫法,只要在你的action中實現(xiàn)ModelDriven接口就可以啦。所以property driven和model driven在struts2中都支持,所以client可以有兩種選擇,

    # re: Starting Struts2--Core Components(3)  回復(fù)  更多評論   

    2007-08-10 10:36 by paul
    期待你的s2所說的零配置的講解啊,annotation,給個例子啊

    posts - 47, comments - 124, trackbacks - 0, articles - 0

    Copyright © puras

    主站蜘蛛池模板: 日本高清免费网站| 成人免费无码大片a毛片软件| 亚洲成年看片在线观看| 亚洲另类无码专区首页| 超pen个人视频国产免费观看| 亚洲大码熟女在线观看| 永久免费视频v片www| www亚洲精品久久久乳| www.91亚洲| 中文成人久久久久影院免费观看| 亚洲精品成人片在线观看精品字幕 | 亚洲国产精品不卡在线电影| 久久久久国产精品免费免费不卡| 亚洲天堂久久精品| 免费H网站在线观看的| 亚洲国产欧美国产综合一区| 国产美女无遮挡免费视频| 特级毛片A级毛片免费播放| 亚洲午夜久久久久久噜噜噜| 99久久久国产精品免费牛牛四川| 亚洲人成网站日本片| 日韩人妻无码免费视频一区二区三区| 手机永久免费的AV在线电影网| 亚洲精品国产精品乱码视色| 亚州免费一级毛片| 真正全免费视频a毛片| 久久青草亚洲AV无码麻豆| 久久国内免费视频| 免费一级毛片在线播放视频免费观看永久 | 国产美女无遮挡免费视频| 久久国产精品免费一区| 亚洲综合图片小说区热久久| 日本不卡免费新一二三区| 你好老叔电影观看免费| 亚洲一级特黄特黄的大片| 亚洲Aⅴ无码一区二区二三区软件| 大地影院MV在线观看视频免费| 亚洲毛片基地4455ww| 久久久久噜噜噜亚洲熟女综合| 亚洲免费福利视频| 人碰人碰人成人免费视频|