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

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

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

    京山游俠

    專注技術(shù),拒絕扯淡
    posts - 50, comments - 868, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    在SpringSide 3 中,使用的MVC框架是Struts 2。Struts 2 向?qū)τ赟truts 1 來說,具有相當(dāng)多的優(yōu)點(diǎn),有很多人都說,用過Struts 2之后,再也不想看Struts 1了。然而,任何東西都有它的復(fù)雜性,Struts 2也不例外,SpringSide 3做了很多工作來簡化Struts 2 的使用。

    先來說說Struts 2的特點(diǎn):
    1、編寫Action變得簡單了,Action變成了簡單的POJO,再也不用和ActionForm、ActionForward打交道了,返回的時(shí)候直接返回字符串即可。如果要訪問Servlet API,則直接使用ServletActionContext類的靜態(tài)方法。
    2、Struts 2提供了插件機(jī)制,允許我們自己為它編寫插件,當(dāng)然,要我自己寫是不現(xiàn)實(shí)的,但是面對(duì)別人寫的琳瑯滿目的插件,我一樣會(huì)昏頭。再網(wǎng)上隨便一搜,就可以發(fā)現(xiàn)40多種Struts 2插件。SpringSide 3選擇的CodeBehind,就是一種Struts 2插件,它的目的是為了簡化配置。
    3、Struts 2提供了攔截器機(jī)制,之所以編寫Action的任務(wù)那么簡單,靠的都是這些攔截器,比如它們可以自動(dòng)解析Web表單和URL參數(shù),把它們注入到Action中。
    4、Struts 2提供了豐富的taglib,當(dāng)然,豐富也代表著我們要化更多的時(shí)間去學(xué)習(xí)。
    5、Struts 2依然提供了Validator和i18n支持。
    等等...

    下面,我們來看看SpringSide 3是怎么使用Struts 2的吧。SpringSide 3的主要目標(biāo)是降低我們使用Struts 2的復(fù)雜性,所以,它選擇了這些辦法:
    1、沒有使用Validator和i18n,對(duì)數(shù)據(jù)的驗(yàn)證交給了JQuery,這變成了表現(xiàn)層的任務(wù),而且JQuery也可以使用AJAX從服務(wù)器端進(jìn)行驗(yàn)證。至于i18n,江南白衣說小網(wǎng)站用不上。
    2、沒有使用Struts 2的UI標(biāo)簽,當(dāng)然也就沒有使用FreeMaker或SiteMesh了。

    當(dāng)然,省掉了一些東西,就省掉了我們不少的學(xué)習(xí)時(shí)間。對(duì)于Struts 2核心的一些東西,我們看看它是怎么做的:

    1、使用CodeBehind插件來簡化配置。使用CodeBehind后,我們就可以不用配置result了,它可以根據(jù)我們Action的返回值自動(dòng)猜測返回的視圖頁面,它猜測的規(guī)則是這樣的:返回頁面的路徑為struts.codebehind.pathPrefix + package namespace + action name + action returnvalue?+?.jsp,action returnvalue為success時(shí),值為空,為其他時(shí),值為"-" + return type。我們來看看SpringSide 3生成的項(xiàng)目中關(guān)于Struts 2的配置文件:
    001.PNG
    其中struts.codebehind.pathPrefix設(shè)置為“/WEB-INF/jsp/”,package的namespace沒有設(shè)置,所以,如果我們的Action為UserAction,則返回success時(shí),就會(huì)返回到/WEB-INF/jsp/user.jsp,如果返回input,則返回到/WEB-INF/jsp/user-input.jsp。這里江南白衣玩了一個(gè)狡猾,他把所有的jsp頁面放到WEB-INF目錄中,別人就沒有辦法直接訪問了,這樣就可以簡化Acegi的配置工作。

    2、關(guān)于攔截器棧
    在上面講Struts 2的特點(diǎn)時(shí),我已經(jīng)說了Struts 2中攔截器的重要作用,在上面的截圖中,package的配置沒有做別的什么事,主要就是配置了攔截器棧。那么攔截器棧是怎么使用的呢?它是在Action類中通過@ParentPackage指定的,如下面的代碼:
    002.PNG

    下面,我來具體說一下攔截器有什么作用。
    ?例子一、我們知道Struts 2中的Action是和Servlet API解耦的,那么如果我們要在Action中訪問Servlet API怎么辦呢?一種辦法就是使用ServletActionContext,如下圖:
    003.PNG
    另外一種辦法,就是讓我們的Action實(shí)現(xiàn)ServletRequestAware接口,如下代碼:

    public ? class ?MyAction? implements ?ServletRequestAware?{
    ???
    private ?HttpServletRequest?request;
    ???
    public ? void ?setServletRequest(HttpServletRequest?request)?{
    ????????
    this .request? = ?request;
    ???}
    ???
    public ?String?execute()? throws ?Exception?{
    ????????
    // ?do?the?work?using?the?request
    ???????? return ?Action.SUCCESS;
    ???}
    }
    這時(shí)候,ServletConfigInterceptor 攔截器就會(huì)把request對(duì)象注入到我們的Action中。

    例子二、ParametersInterceptor 攔截器會(huì)自動(dòng)解析web表單或URL參數(shù),并把它們注入到Action中。但是很多時(shí)候,我們不愿意我們的Action具有太多的屬性,因?yàn)橐淮蠖训膅et、set方法看起來太亂糟糟,我們希望有一個(gè)專門的Model對(duì)象來存儲(chǔ)這些值,而且剛好我們?yōu)镠ibernate設(shè)計(jì)的Entity類用來做Model正合適。這時(shí),我們可以讓我們的Action實(shí)現(xiàn)ModelDriven接口,讓getModel()方法返回我們的entity對(duì)象即可。這正是SpringSide 3采取的方法,如下圖的代碼片斷:
    004.PNG
    這時(shí)候,ModelDrivenInterceptor攔截器就會(huì)幫助我們把解析的URL參數(shù)或表單數(shù)據(jù)注入到entity的屬性中,而不是Action中。

    例子三、Preparable 接口聯(lián)合PrepareInterceptor攔截器一起工作,可以讓action在執(zhí)行execute() 方法前, 執(zhí)行一個(gè)prepare()方法,這也正是SpringSide 3的工作方式。

    3、關(guān)于Action
    有了上面對(duì)CodeBehind的理解和對(duì)攔截器棧的理解后,再來理解SpringSide 3中的Action就再簡單不過了,SpringSide 3中Action的繼承樹如下:
    005.PNG

    其中ActionSupport類是Struts 2提供的,另外兩個(gè)類是白衣自己擴(kuò)展的。其中SimpleActionSupport主要是提供了一些繞過jsp頁面直接輸出字符串的方法,不值一談。而CRUDActionSupport就比較復(fù)雜,如下:
    public?abstract?class?CRUDActionSupport<T>?extends?SimpleActionSupport?implements?ModelDriven<T>,?Preparable?{
    ????
    /**
    ?????*?進(jìn)行CUD操作后,以redirect方式重新打開action默認(rèn)頁的result名.
    ?????
    */
    ????
    public?static?final?String?RELOAD?=?"reload";

    ????
    /**
    ?????*?Action函數(shù),默認(rèn)action函數(shù),默認(rèn)指向list函數(shù).
    ?????
    */
    ????@Override
    ????
    public?String?execute()?throws?Exception?{
    ????????
    return?list();
    ????}

    ????
    /**
    ?????*?Action函數(shù),顯示Entity列表.
    ?????*?return?SUCCESS.
    ?????
    */
    ????
    public?abstract?String?list()?throws?Exception;

    ????
    /**
    ?????*?Action函數(shù),新增或修改Entity.?
    ?????*?return?RELOAD.
    ?????
    */
    ????
    public?abstract?String?save()?throws?Exception;

    ????
    /**
    ?????*?Action函數(shù),刪除Entity.
    ?????*?return?RELOAD.
    ?????
    */
    ????
    public?abstract?String?delete()?throws?Exception;

    ????
    /**
    ?????*?在save()前執(zhí)行二次綁定.
    ?????
    */
    ????
    public?void?prepareSave()?throws?Exception?{
    ????????prepareModel();
    ????}

    ????
    /**
    ?????*?在input()前執(zhí)行二次綁定.
    ?????
    */
    ????
    public?void?prepareInput()?throws?Exception?{
    ????????prepareModel();
    ????}

    ????
    /**
    ?????*?屏蔽公共的二次綁定.
    ?????
    */
    ????
    public?void?prepare()?throws?Exception?{
    ????}

    ????
    /**
    ?????*?等同于prepare()的內(nèi)部函數(shù).?
    ?????
    */
    ????
    protected?abstract?void?prepareModel()?throws?Exception;
    }


    第一,它做了把CRUD操作放到了同一個(gè)Action中的操作,這樣可以少寫幾個(gè)Action。這個(gè)工作難度不大,我覺得白衣此舉,主要是為了規(guī)范CRUD函數(shù)的命名。在Struts 2中,如果我們要訪問的不是默認(rèn)的excute方法,可以使用如/user!save.action的格式,這樣訪問的就是UserAction的save方法。
    第二,它實(shí)現(xiàn)了ModelDriven接口和Preparable接口,關(guān)于這兩個(gè)接口,我在前面講攔截器的時(shí)候已經(jīng)提到過了,所以很容易理解。我們可以把我們?yōu)镠ibernate設(shè)計(jì)的entity類作為Model,也可以把初始化這些entity的工作放到prepareSave()和prepareInput()方法中,這兩個(gè)方法將會(huì)在save()和input()方法執(zhí)行前自動(dòng)執(zhí)行。
    第三,它定義了一個(gè)靜態(tài)變量RELOAD,定義這個(gè)變量的目的是為了定義一個(gè)result的需要。CodeBehind中,大部分的result可以自己猜測,對(duì)于不能猜測的,需要使用@Results指定,如下代碼:
    006.PNG

    ?

    ?好了,對(duì)SpringSide 3中Struts 2的分析就寫到這里了。總之,使用SpringSide 3時(shí),對(duì)于Action這一塊非常簡單,如果不設(shè)及到CRUD操作,就繼承SimpleActionSupport,如果涉及到CRUD操作,就繼承CRUDActionSupport,并在getModel()\save()\prepareSave\input()\prepareInput()等框框中填入適當(dāng)?shù)拇a即可。


    評(píng)論

    # re: SpringSide 3 中的 Struts 2  回復(fù)  更多評(píng)論   

    2008-12-24 15:38 by 虎嘯龍吟
    非常不錯(cuò)!比看springSide的源碼清晰多了。節(jié)省了大量的時(shí)間。期待有更多的
    springSide的文章。

    # re: SpringSide 3 中的 Struts 2  回復(fù)  更多評(píng)論   

    2008-12-24 16:27 by blablalba
    Hey,大俠,我從springside的論壇上尋到這兒來。
    http://forum.springside.org.cn/viewthread.php?tid=3232&extra=&page=1
    是關(guān)于配多數(shù)據(jù)源的,你在回帖中提到的事務(wù)配置方面的問題我也碰到了。
    <tx:annotation-driven transaction-manager="transactionManager" />

    ms不能有多個(gè)的<tx:annotation-driven>??

    現(xiàn)在提供一個(gè)解決方案么?不要JTA咯

    # re: SpringSide 3 中的 Struts 2  回復(fù)  更多評(píng)論   

    2008-12-24 17:08 by lx281
    謝謝,文章寫的很清晰明白,學(xué)習(xí)struts2中,順便看看springside

    # re: SpringSide 3 中的 Struts 2  回復(fù)  更多評(píng)論   

    2008-12-24 20:11 by 海邊沫沫
    @blablalba
    等我的下一篇,下一篇我會(huì)寫關(guān)于數(shù)據(jù)訪問方面的內(nèi)容。

    # re: SpringSide 3 中的 Struts 2  回復(fù)  更多評(píng)論   

    2009-01-15 15:19 by 向往藍(lán)天
    寫的很好啊,謝謝了,我剛開始使用springside
    看了你的前一篇文章,覺得思路清晰多了,
    我是使用maven 來管理的,但是maven 我剛開始接觸
    而springside的主頁上的文檔說的比較凌亂,應(yīng)該是自己的技術(shù)太淺的緣故
    能不能麻煩你寫便關(guān)于maven 結(jié)合eclipse3.4的文章啊

    # re: SpringSide 3 中的 Struts 2  回復(fù)  更多評(píng)論   

    2009-01-16 11:23 by talangniao
    如果我想使用FreeMarker作模板,
    怎樣配置映射到WEB-INF/ftl/下的.ftl文件?

    # re: SpringSide 3 中的 Struts 2  回復(fù)  更多評(píng)論   

    2009-01-16 11:27 by talangniao
    使用FreeMarker作模板,是不是要進(jìn)行配置namespace?
    要怎樣進(jìn)行配置?

    # re: SpringSide 3 中的 Struts 2[未登錄]  回復(fù)  更多評(píng)論   

    2009-02-11 10:49 by sniper
    看了文章寫的挺詳細(xì)的,中間有個(gè)不明白的地方:prepareSave()和prepareInput()是如何調(diào)用的,因?yàn)榭戳薖reparable接口只有一個(gè)方法prepare(),在實(shí)現(xiàn)接口時(shí)也只是一個(gè)空方法,不知道是如何調(diào)用到相應(yīng)的prepare*方法的,希望能幫忙說明一下。

    # re: SpringSide 3 中的 Struts 2[未登錄]  回復(fù)  更多評(píng)論   

    2009-02-11 10:57 by sniper
    呵呵查看了一些關(guān)于PrepareInterceptor的文章,原來是攔截器中處理的。http://willson-tien.javaeye.com/blog/270596

    # re: SpringSide 3 中的 Struts 2[未登錄]  回復(fù)  更多評(píng)論   

    2009-02-12 22:36 by haha
    寫得不錯(cuò),謝謝。springside3還是有很多難點(diǎn)之處。下載的源代碼注釋不是很清楚,希望樓主能寫更詳細(xì)的springside的說明文檔和流程結(jié)構(gòu)圖。
    再次感謝!

    # re: SpringSide 3 中的 Struts 2  回復(fù)  更多評(píng)論   

    2009-04-28 10:52 by fmq2008
    user.action的 url 怎么在ss3中配置成user.html

    # re: SpringSide 3 中的 Struts 2  回復(fù)  更多評(píng)論   

    2009-05-06 11:17 by 海邊沫沫
    @fmq2008
    很簡單,在Struts的配置文件中加入:
    <constant name="struts.action.extension" value="html">

    # re: SpringSide 3 中的 Struts 2[未登錄]  回復(fù)  更多評(píng)論   

    2009-12-31 13:11 by bean
    如何在原有的攔截器棧中增加配置一個(gè)自己的攔截器?
    我添加后,不能起作用,代碼如下
    <package name="crud-default" extends="convention-default">

    <interceptors>
    <interceptor name="checkUserAndEncoding"
    class="CheckUserAndEncodingIntercept" />

    <interceptor-stack name="crudStack">
    <interceptor-ref name="checkUserAndEncoding" />
    <interceptor-ref name="store">
    <param name="operationMode">AUTOMATIC</param>
    </interceptor-ref>
    <interceptor-ref name="paramsPrepareParamsStack" />

    </interceptor-stack>
    </interceptors>
    <default-interceptor-ref name="crudStack" />
    </package>
    主站蜘蛛池模板: 亚洲av无码专区青青草原| 日韩一级免费视频| 久久午夜夜伦鲁鲁片无码免费| 一级毛片成人免费看a| 日日摸夜夜添夜夜免费视频| 黄色网页免费观看| 免费人成网站永久| 一级做a毛片免费视频| av成人免费电影| 中文字幕免费在线看线人动作大片| 一区二区三区免费视频观看| 二区久久国产乱子伦免费精品| 国产精品免费视频观看拍拍 | 亚洲v国产v天堂a无码久久| 国产又大又粗又硬又长免费| 免费看国产一级片| 久久亚洲色一区二区三区| 亚洲午夜国产精品无码老牛影视| 亚洲三区在线观看无套内射| 亚洲成人中文字幕| 亚洲最新黄色网址| 亚洲色大成网站www| 国产亚洲漂亮白嫩美女在线| 一级白嫩美女毛片免费| 97超高清在线观看免费视频| 少妇无码一区二区三区免费| 妻子5免费完整高清电视| 免费看的一级毛片| 亚洲一区二区三区免费| 久久亚洲精品成人777大小说| 亚洲成在人线电影天堂色| 亚洲国产精品无码久久久秋霞1| 免费毛片毛片网址| 国产一精品一AV一免费| 又黄又爽又成人免费视频| 国产大片免费观看中文字幕| 亚洲中文久久精品无码| 久久精品国产亚洲AV无码偷窥| 久久综合久久综合亚洲| www一区二区www免费| 3d成人免费动漫在线观看|