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

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

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

    posts - 41,  comments - 8,  trackbacks - 0
    關(guān)鍵字: Struts2 COC
    摘要:介紹Struts2中的零配置(Zero Configuration),以及如何用COC來更好地簡化Struts2的配置。在第一章,我使用Maven來創(chuàng)建一個(gè)起點(diǎn)項(xiàng)目;第二章,以該項(xiàng)目為例,講解如何使用Struts2的零配置;第三章,論述第二章中的實(shí)現(xiàn)方式的缺陷,然后講解如何使用COC來改進(jìn)這些缺陷,并進(jìn)一步簡化Struts2的配置。附件是這篇文章用到的示例代碼。

    一、從零開始

    這里,我將建立一個(gè)新的示例項(xiàng)目,作為講解的起點(diǎn)。我使用JDK 6、Maven 2、Eclipse 3.3來建立這個(gè)示例,如果讀者對Maven2不熟也沒關(guān)系,這只是個(gè)示例。
    首先,運(yùn)行下邊的命令:
                    mvn archetype:create -DgroupId=demo.struts -DartifactId=demo-struts-coc -DarchetypeArtifactId=maven-archetype-webapp
    這會(huì)建立如下的目錄結(jié)構(gòu):
     |- POM.xml
     |- src
         |- main
             |- resources
             |- webapp
                 |- index.jsp
                 |- WEB-INF
                     |- web.xml
    然后我們在src/main目錄下新建一個(gè)名為java的目錄,用來放置java代碼。在src下建立test目錄,并在test目錄下建立java目錄,用來放置測試代碼。另外,我這個(gè)示例不想使用JSP,所以我將src/main/webapp目錄下的index.jsp改為index.html。
    現(xiàn)在,需要配置該項(xiàng)目要用到哪些lib。在POM.xml中加入struts2-core:
    xml 代碼
     
    1. <dependency>  
    2.     <groupId>org.apache.struts</groupId>  
    3.     <artifactId>struts2-core</artifactId>  
    4.     <version>2.0.9</version>  
    5. </dependency>  

    另外,我想在Eclipse里使用jetty來啟動(dòng)項(xiàng)目并進(jìn)行測試,所以在POM.xml中再加入jetty、jetty-util、servlet-api等的依賴,詳情見附件。
    我希望使用Eclipse來作為這個(gè)項(xiàng)目的IDE,所以,我在命令行狀態(tài)下,進(jìn)入這個(gè)項(xiàng)目所在的目錄,運(yùn)行:
                    mvn eclipse:eclipse
    然后使用Eclipse導(dǎo)入這個(gè)項(xiàng)目。如果你是第一次用Eclipse導(dǎo)入用Maven生成的項(xiàng)目,那你需要在Eclipse里配置一個(gè)名叫M2_REPO的Variable,指向你的Maven 2的repository目錄。缺省情況下,它應(yīng)該位于${user.home}/.m2/repository。
    OK!現(xiàn)在我們已經(jīng)可以在Eclipse中進(jìn)行工作了。
    修改src/main/webapp/WEB-INF/web.xml,加入struts2的FilterDispatcher并設(shè)置filter-mapping。在這個(gè)示例中我將url-pattern設(shè)為"/app/*",也就是說,url的匹配是基于路徑來做的。這只是我的個(gè)人喜好而已,你也可以將它設(shè)成"*"。
    既然是在講struts2的零配置,當(dāng)然是可以不要任何配置文件的。但是為了更好地進(jìn)行“配置”,我還是建立了struts.xml文件(在src/main/resources目錄下)。我不喜歡url最后都有個(gè)action后綴,現(xiàn)在,我在struts.xml中配置struts.action.extension,將這個(gè)后綴去掉:
    xml 代碼
     
    1. <struts>  
    2.     <constant name="struts.action.extension" value="" />  
    3. </struts>  

    然后我在src/test/java下建立demo/RunJetty.java文件,main方法如下:
    java 代碼
     
    1. public static void main(String[] args) throws Exception {  
    2.     Server server = new Server(8080); //也可以改成其它端口  
    3.     File rootDir = new File(RunJetty.class.getResource("/").getPath()).getParentFile().getParentFile();  
    4.     String webAppPath = new File(rootDir, "src/main/webapp").getPath();  
    5.     new WebAppContext(server, webAppPath, "/");  
    6.     server.start();  
    7. }  

    現(xiàn)在,在Eclipse里運(yùn)行或調(diào)試這個(gè)RunJetty.java,用瀏覽器打開http://localhost:8080/看看吧。如果不出問題,應(yīng)該可以訪問到webapp目錄下的index.html了。有了Jetty,你還在用MyEclipse或其它插件么?

    二、零配置

    首先要澄清一點(diǎn),這里說的零配置并不是一點(diǎn)配置都沒有,只是說配置很少而已。
    Struts2(我只用過Struts 2.0.6和2.0.9,不清楚其它版本是否支持零配置)引入了零配置的新特性,元數(shù)據(jù)可以通過規(guī)則和注解來表達(dá):A "Zero Configuration" Struts application or plugin uses no additional XML or properties files. Metadata is expressed through convention and annotation.
    目前,這個(gè)新特性還在測試階段,但經(jīng)過一段時(shí)間的使用,我覺得這個(gè)特性已經(jīng)可用。下面我講一下如何使用它。
    1. Actions的定位
    以前需要在xml配置文件中配置Action的name和class,如果使用零配置,所帶來的一個(gè)問題就是如何定位這些Action。我們需要在web.xml中找到struts2的filter的配置,增加一個(gè)名為actionPackages的init-param,它的值是一個(gè)以逗號(hào)分隔的Java包名列表,比如:demo.actions1,demo.actions2。struts2將會(huì)掃描這些包(包括這些包下邊的子包),在這些包下,所有實(shí)現(xiàn)了Action接口的或者是類名以“Action”結(jié)尾的類都會(huì)被檢查到,并被當(dāng)做Action。
    以前,我們寫Action必須要實(shí)現(xiàn)Action接口或者繼承ActionSupport。但是,上面提到的類名以"Action"結(jié)尾的類并不需要這樣做,它可以是一個(gè)POJO,Struts2支持POJO Action!
    下面是actionPackages的配置示例:
    xml 代碼
     
    1. <filter>  
    2.   <filter-name>struts2</filter-name>  
    3.   <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>  
    4.   <init-param>  
    5.     <param-name>actionPackages</param-name>  
    6.     <param-value>demo.actions1,demo.actions2</param-value>  
    7.   </init-param>  
    8. </filter>  

    2. 示例
    現(xiàn)在我們建立demo.actions1.app.person和demo.actions2.app.group兩個(gè)包,在demo.actions1.app.person包下建立ListPeopleAction.java,在demo.actions2.app.group下建立ListGroupAction.java。作為示例,這兩個(gè)類只是包含一個(gè)execute方法,返回"success"或"error",其它什么都不做:
    java 代碼
     
    1. public String execute() {  
    2.     return "success";  
    3. }  

    在Filter的配置中,我指定actionPackages為demo.actions1,demo.actions2,當(dāng)系統(tǒng)啟動(dòng)時(shí),Struts2就會(huì)在這兩個(gè)包下掃描到demo.actions1.app.person.ListPeopleAction和demo.actions2.app.group.ListGroupAction。

    3. Action and Package name
    Struts2掃描到Action后,從actionPackages指定的包開始,子包名會(huì)成為這個(gè)Action的namespace,而Action的name則由這個(gè)Action的類名決定。將類名首字母小寫,如果類名以Action結(jié)尾,則去掉"Action"后綴,形成的名字就是這個(gè)Action的名字。在如上所述的示例中,actionPackages指定為demo.actions1,demo.actions2,那么你可以這樣訪問demo.actions1.app.person.ListPeopleAction:
                    http://localhost:8080/app/person/listPeople

    4. Results
    Struts2是通過"Result"和"Results"兩個(gè)類級(jí)別的annotations來指定Results的。
    作為示例,我們在webapp目錄下建兩個(gè)html文件:success.html和error.html,隨便寫點(diǎn)什么內(nèi)容都可以。現(xiàn)在假設(shè)我們訪問/app/person/listPeople時(shí),或Action返回success就轉(zhuǎn)到success.html頁面,若是error就轉(zhuǎn)到error.html頁面,這只需要在ListPeopleAction類上加上一段注解就可以了:
    java 代碼
     
    1. @Results({  
    2.     @Result(name="success", type=NullResult.class, value = "/success.html", params = {}),  
    3.     @Result(name="error", type=NullResult.class, value = "/error.html", params = {})  
    4. })  
    5. public class ListPeopleAction {  
    6.     public String execute() {  
    7.         return "success";  
    8.     }  
    9. }  

    同上,我們給ListGroupAction也加上注解。
    現(xiàn)在,我們已經(jīng)完成了一個(gè)零配置的示例。我們并沒有在xml文件里配置ListPeopleAction和ListGroupAction,但它們已經(jīng)可以工作了!
    用Eclipse運(yùn)行RunJetty,然后用瀏覽器訪問http://localhost:8080/app/person/listPeople和http://localhost:8080/app/group/listGroup看看,是不是正是success.html(或error.html)的內(nèi)容?

    5. Namespaces
    如上所述,namespace由包名所形成,但我們可以使用"Namespace"注解來自己指定namespace。

    6. Parent Package
    這個(gè)配置用得較少。Struts2提供一個(gè)"ParentPackage"注解來標(biāo)識(shí)Action應(yīng)該是屬于哪個(gè)package。

    三、使用COC

    如上所述,Struts2用注解來實(shí)現(xiàn)零配置。然而,這不是我喜歡的方式。在我看來,這不過是將配置從XML格式換成了注解方式,并不是真的零配置。而且,這種方式也未必比XML形式的配置更好。另外,對元數(shù)據(jù)的修改必然會(huì)導(dǎo)致項(xiàng)目的重新編譯和部署。還有,現(xiàn)在的Struts2版本似乎對Result注解中的params的處理有些問題。
    其實(shí),Struts2的actionPackages配置已經(jīng)使用了COC,那為什么不能為Results也實(shí)現(xiàn)COC,從而去除這些每個(gè)Action都要寫的注解?
    在嚴(yán)謹(jǐn)?shù)捻?xiàng)目中,package、action的名稱和頁面的路徑、名稱一定存在著某種關(guān)系。比如,頁面的路徑可能和package是對應(yīng)的,頁面的名稱可能和action的名稱是對應(yīng)的,或是根據(jù)某種法則運(yùn)算得到。我們知道webwork2和struts2有個(gè)配置叫g(shù)lobal-results。我們?yōu)槭裁床荒芨鶕?jù)這些對應(yīng)規(guī)則寫個(gè)Result,將它配到global-results中,從而真正免去result的配置?
    事實(shí)上,我推薦Struts2的使用者只用Struts2輸出XML或JSON,放棄UI,頁面這層還是使用標(biāo)準(zhǔn)的HTML、CSS和一些JS組件來展現(xiàn)。許多人反映Struts2慢,確實(shí),Struts2是慢,很慢!慢在哪兒?很大一部分因素是UI這層引起的,特別是使用了過多的Struts2的tag,并使用了ajax theme。但是,如果我們放棄了Struts2的笨拙的UI,Result只輸出XML或JSON,UI則使用標(biāo)準(zhǔn)的HTML+CSS,使用JS組件(DOJO、Adobe Spry Framework、YUI-Ext等)來操作Struts2的輸出數(shù)據(jù),情況將會(huì)如何?我們會(huì)得到一個(gè)高性能、高可配的、UI和應(yīng)用服務(wù)器的職責(zé)分割更為明確、合理的、更易于靜態(tài)化部署的開發(fā)組合。
    這似乎是閹割了Struts2,但是這樣閹割過的Struts2擺脫了性能低下的包袱,更輕、更現(xiàn)代化。
    有些扯遠(yuǎn)了,言歸正傳,不管是讓Struts2輸出XML或JSON,還是輸出頁面,我們都有辦法根據(jù)項(xiàng)目的規(guī)則寫一個(gè)Result,將它配到global-results中,從而大大減少Result的配置。
    假設(shè)我們讓Struts2只輸出JSON,有個(gè)jsonplugin可以做這件事。使用JsonResult時(shí),不再需要知道頁面的位置、名稱等信息,它僅僅是數(shù)據(jù)輸出,那么我們就可以將這個(gè)Result配成全局的,大部分Action將不再需要Result的配置。
    作為示例,我假設(shè)我的例子中輸出的兩個(gè)html頁面(success.html和error.html)是JSON,我們看看怎么免去我例子中的兩個(gè)Action的Result注解。
    首先,我們刪去ListPeopleAction和ListGroupAction兩個(gè)Action的注解,并修改struts.xml文件,加入:
    xml 代碼
     
    1. <package name="demo-default" extends="struts-default">  
    2. <global-results>  
    3. <result name="success">/success.html</result>  
    4. </global-results>  
    5. </package>  

    請記住這只是一個(gè)示例,為了方便,我沒在項(xiàng)目中加入jsonplugin來作真實(shí)的演示,我只是假設(shè)這個(gè)success是json輸出,讀者可以自行使用jsonplugin來作實(shí)驗(yàn)。

    現(xiàn)在,離成功不遠(yuǎn)了,但是項(xiàng)目仍然不能正常運(yùn)行。我們的Action返回success,但并不會(huì)匹配到global-results中配置。為什么呢?因?yàn)椋覀冞@里是把global-results配置到"demo-default"這個(gè)package下的,而Struts2根據(jù)actionPackages找到的Action不會(huì)匹配到這個(gè)package上。解決辦法也很簡單,還記得上面講到的Parent Package吧?給Action加個(gè)注解,指定ParentPackage為"demo-default"。但這樣可不是我喜歡的,其實(shí)有更好的辦法,我們在struts.xml中加個(gè)constant就好了:
    xml 代碼
     
    1. <constant name="struts.configuration.classpath.defaultParentPackage" value="demo-default" />  

    現(xiàn)在,大功告成!運(yùn)行RunJetty來測試下吧!你可以訪問/app/person/listPeople,可以訪問/app/group/listGroup,而所有的配置僅僅是web.xml和struts.xml中的幾行,我們的Java代碼中也沒有加注解。如果再加上幾百個(gè)Action呢?配置仍然就這幾行。
    可是,某些Action確實(shí)需要配置怎么辦?對這些Action,你可以加注解,也可以針對這些Action來寫些XML配置。一個(gè)項(xiàng)目中,大部分Action的配置是可以遵從一定規(guī)則的,可以使用規(guī)則來簡化配置,只有少部分需要配置,這就是COC。

    posted on 2008-10-04 14:08 Loy Fu 閱讀(1036) 評論(0)  編輯  收藏 所屬分類: struts
    主站蜘蛛池模板: 国产99在线|亚洲| 成人免费ā片在线观看| 免费A级毛片无码A∨男男| 中文在线观看国语高清免费| 中文字幕亚洲精品资源网| 毛片免费全部免费观看| 一区二区三区免费电影| 亚洲人妖女同在线播放| 亚洲Av无码乱码在线znlu| 全部免费毛片在线播放| 午夜亚洲国产精品福利| 亚洲VA中文字幕不卡无码| 在线成人a毛片免费播放 | 亚洲人成色4444在线观看| 亚洲午夜福利精品久久| 很黄很黄的网站免费的| eeuss免费天堂影院| 亚洲成a人片在线看| 亚洲中文字幕不卡无码| 毛片免费vip会员在线看| 成全视频免费观看在线看| 亚洲码和欧洲码一码二码三码| 亚洲区小说区激情区图片区| 好吊妞998视频免费观看在线| 国产一级婬片A视频免费观看| 亚洲中文字幕久久精品无码VA| 久久精品国产亚洲网站| 亚洲高清无码综合性爱视频| 97在线观看永久免费视频| 国产免费AV片在线观看| 黄色免费在线观看网址| 久久亚洲精品国产精品婷婷| 亚洲国产另类久久久精品小说| 国产乱子影视频上线免费观看| 嘿嘿嘿视频免费网站在线观看| 亚洲天堂免费在线视频| 国产精品亚洲а∨无码播放不卡| 亚洲性一级理论片在线观看| 亚洲精品国产精品乱码视色| 免费人成激情视频| 成人免费在线视频|