<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) 評(píng)論(3)  編輯  收藏 所屬分類(lèi): Struts2.0

    Result Types

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

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

    Request and Form Data

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

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

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

    Accessing Business Services

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

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

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

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

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

    攔截器會(huì)為必要的接口和setters注入必要的對(duì)象注入.

    Accessing Data from the Action

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

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

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

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

    Interceptors

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

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

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

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

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

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

    Configuration

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

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

     

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

     

    我們同樣需要確認(rèn)將攔截器應(yīng)用到需要它的Action上.這可以通過(guò)兩種方法實(shí)現(xiàn).第一種是將攔截器分配給每個(gè)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上的攔截器沒(méi)有數(shù)量的限制.現(xiàn)在所需要的就是排列攔截器的順序,它們都將被執(zhí)行.

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

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


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

    現(xiàn)在已將攔截器配置到了Action映射上了,它將在每個(gè)映射的URL請(qǐng)求時(shí)被執(zhí)行.但是這樣有一些限制,更多的時(shí)候,我們需要將多個(gè)攔截器指派給一個(gè)Action.事實(shí)上,Struts2里基礎(chǔ)的功能攔截器有很多,給每個(gè)Action指派7,8個(gè)攔截器也不是不可能的事.你可以假設(shè)一下,為每個(gè)Action配置各個(gè)攔截器,很快就會(huì)變得極難管理.因?yàn)檫@個(gè)原因,可使用攔截器棧來(lái)管理攔截器.這里有個(gè)例子,來(lái)自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>

     

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

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

     

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

     

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

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


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

    Implementing Interceptors

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

     

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

     

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

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

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

    Value Stack / OGNL

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

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

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

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

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

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

    Result Types

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

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

     

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

     

    Configuration

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

     

    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é)果類(lèi)型并將它們配置到你的WEB應(yīng)用中.一些常用的結(jié)果類(lèi)型已經(jīng)存在,所以,在你創(chuàng)建自己的之前,你應(yīng)該先看看你想創(chuàng)建的類(lèi)型是否已經(jīng)存在.

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

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

     

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

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

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

    Feedback

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

    2007-08-10 08:30 by icc
    不錯(cuò),多謝!!

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

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

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

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

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

    Copyright © puras

    主站蜘蛛池模板: 亚洲AV无码专区在线电影成人 | 亚洲精品久久久www| 亚洲免费日韩无码系列| 久久综合日韩亚洲精品色| 免费无码AV片在线观看软件| 免费看一级一级人妻片| 亚洲成人动漫在线| 麻豆国产入口在线观看免费| 曰批全过程免费视频在线观看无码 | 亚洲.国产.欧美一区二区三区| 国产精品亚洲w码日韩中文| 8x8×在线永久免费视频| jzzijzzij在线观看亚洲熟妇| 亚洲A∨无码无在线观看| 四虎在线免费播放| 你是我的城池营垒免费看| 亚洲高清乱码午夜电影网| 亚洲成AV人片在线观看无| 在线免费观看视频你懂的| 中文字字幕在线高清免费电影| 亚洲av无码国产综合专区| 黑人大战亚洲人精品一区| 一二三四视频在线观看中文版免费 | 精品国产污污免费网站入口在线| 亚洲午夜电影在线观看| 亚洲桃色AV无码| 女性无套免费网站在线看| 一区二区免费视频| 一本大道一卡二大卡三卡免费| 亚洲人成人77777在线播放| 亚洲精品字幕在线观看| 国产免费午夜a无码v视频| 中文字幕av无码无卡免费| 黄色片免费在线观看| 国产成人亚洲综合a∨| 亚洲人成影院在线高清| 亚洲av无码一区二区三区乱子伦 | 亚洲国产精品久久66| 久久精品国产精品亚洲人人| 大学生高清一级毛片免费| www视频免费看|