<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
    關鍵字: Struts2 COC
    摘要:介紹Struts2中的零配置(Zero Configuration),以及如何用COC來更好地簡化Struts2的配置。在第一章,我使用Maven來創建一個起點項目;第二章,以該項目為例,講解如何使用Struts2的零配置;第三章,論述第二章中的實現方式的缺陷,然后講解如何使用COC來改進這些缺陷,并進一步簡化Struts2的配置。附件是這篇文章用到的示例代碼。

    一、從零開始

    這里,我將建立一個新的示例項目,作為講解的起點。我使用JDK 6、Maven 2、Eclipse 3.3來建立這個示例,如果讀者對Maven2不熟也沒關系,這只是個示例。
    首先,運行下邊的命令:
                    mvn archetype:create -DgroupId=demo.struts -DartifactId=demo-struts-coc -DarchetypeArtifactId=maven-archetype-webapp
    這會建立如下的目錄結構:
     |- POM.xml
     |- src
         |- main
             |- resources
             |- webapp
                 |- index.jsp
                 |- WEB-INF
                     |- web.xml
    然后我們在src/main目錄下新建一個名為java的目錄,用來放置java代碼。在src下建立test目錄,并在test目錄下建立java目錄,用來放置測試代碼。另外,我這個示例不想使用JSP,所以我將src/main/webapp目錄下的index.jsp改為index.html。
    現在,需要配置該項目要用到哪些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來啟動項目并進行測試,所以在POM.xml中再加入jetty、jetty-util、servlet-api等的依賴,詳情見附件。
    我希望使用Eclipse來作為這個項目的IDE,所以,我在命令行狀態下,進入這個項目所在的目錄,運行:
                    mvn eclipse:eclipse
    然后使用Eclipse導入這個項目。如果你是第一次用Eclipse導入用Maven生成的項目,那你需要在Eclipse里配置一個名叫M2_REPO的Variable,指向你的Maven 2的repository目錄。缺省情況下,它應該位于${user.home}/.m2/repository。
    OK!現在我們已經可以在Eclipse中進行工作了。
    修改src/main/webapp/WEB-INF/web.xml,加入struts2的FilterDispatcher并設置filter-mapping。在這個示例中我將url-pattern設為"/app/*",也就是說,url的匹配是基于路徑來做的。這只是我的個人喜好而已,你也可以將它設成"*"。
    既然是在講struts2的零配置,當然是可以不要任何配置文件的。但是為了更好地進行“配置”,我還是建立了struts.xml文件(在src/main/resources目錄下)。我不喜歡url最后都有個action后綴,現在,我在struts.xml中配置struts.action.extension,將這個后綴去掉:
    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. }  

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

    二、零配置

    首先要澄清一點,這里說的零配置并不是一點配置都沒有,只是說配置很少而已。
    Struts2(我只用過Struts 2.0.6和2.0.9,不清楚其它版本是否支持零配置)引入了零配置的新特性,元數據可以通過規則和注解來表達:A "Zero Configuration" Struts application or plugin uses no additional XML or properties files. Metadata is expressed through convention and annotation.
    目前,這個新特性還在測試階段,但經過一段時間的使用,我覺得這個特性已經可用。下面我講一下如何使用它。
    1. Actions的定位
    以前需要在xml配置文件中配置Action的name和class,如果使用零配置,所帶來的一個問題就是如何定位這些Action。我們需要在web.xml中找到struts2的filter的配置,增加一個名為actionPackages的init-param,它的值是一個以逗號分隔的Java包名列表,比如:demo.actions1,demo.actions2。struts2將會掃描這些包(包括這些包下邊的子包),在這些包下,所有實現了Action接口的或者是類名以“Action”結尾的類都會被檢查到,并被當做Action。
    以前,我們寫Action必須要實現Action接口或者繼承ActionSupport。但是,上面提到的類名以"Action"結尾的類并不需要這樣做,它可以是一個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. 示例
    現在我們建立demo.actions1.app.person和demo.actions2.app.group兩個包,在demo.actions1.app.person包下建立ListPeopleAction.java,在demo.actions2.app.group下建立ListGroupAction.java。作為示例,這兩個類只是包含一個execute方法,返回"success"或"error",其它什么都不做:
    java 代碼
     
    1. public String execute() {  
    2.     return "success";  
    3. }  

    在Filter的配置中,我指定actionPackages為demo.actions1,demo.actions2,當系統啟動時,Struts2就會在這兩個包下掃描到demo.actions1.app.person.ListPeopleAction和demo.actions2.app.group.ListGroupAction。

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

    4. Results
    Struts2是通過"Result"和"Results"兩個類級別的annotations來指定Results的。
    作為示例,我們在webapp目錄下建兩個html文件:success.html和error.html,隨便寫點什么內容都可以?,F在假設我們訪問/app/person/listPeople時,或Action返回success就轉到success.html頁面,若是error就轉到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也加上注解。
    現在,我們已經完成了一個零配置的示例。我們并沒有在xml文件里配置ListPeopleAction和ListGroupAction,但它們已經可以工作了!
    用Eclipse運行RunJetty,然后用瀏覽器訪問http://localhost:8080/app/person/listPeople和http://localhost:8080/app/group/listGroup看看,是不是正是success.html(或error.html)的內容?

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

    6. Parent Package
    這個配置用得較少。Struts2提供一個"ParentPackage"注解來標識Action應該是屬于哪個package。

    三、使用COC

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

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

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

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

    posted on 2008-10-04 14:08 Loy Fu 閱讀(1036) 評論(0)  編輯  收藏 所屬分類: struts
    主站蜘蛛池模板: 亚洲欧洲视频在线观看| 77777亚洲午夜久久多人| 亚洲精品视频观看| 91视频免费网址| 亚洲日韩区在线电影| 午夜理伦剧场免费| 亚洲人成电影福利在线播放| 性xxxx视频免费播放直播| 亚洲欧洲国产日韩精品| 99精品在线免费观看| 久久精品国产亚洲av水果派| 1000部免费啪啪十八未年禁止观看| 久久综合亚洲色一区二区三区| 中文字幕成人免费视频| 亚洲av片不卡无码久久| 中文字幕影片免费在线观看| 亚洲中文字幕AV每天更新| 日韩免费高清视频| 亚洲一区二区三区免费| 亚洲av日韩av高潮潮喷无码| 59pao成国产成视频永久免费| 亚洲AV成人噜噜无码网站| 日韩成人在线免费视频| 插鸡网站在线播放免费观看| 亚洲尹人香蕉网在线视颅| 在线看片免费不卡人成视频| 国产精品亚洲片在线花蝴蝶| 最新国产AV无码专区亚洲 | 亚洲AV中文无码乱人伦在线视色| 日韩毛片免费一二三| 九月丁香婷婷亚洲综合色| 亚洲免费中文字幕| 国产亚洲午夜精品| 久久亚洲精品成人AV| 国产精品黄页在线播放免费| a毛片免费播放全部完整| 亚洲日本久久一区二区va| 亚洲一级片免费看| 永久免费毛片在线播放| 又硬又粗又长又爽免费看| 亚洲一级视频在线观看|