stone2083

          Struts2.1.6--想用通配符,不容易

          初次使用Struts2,老老實實為每個action method配置url mapping文件。
          時間長了,難為覺得繁瑣,為何不使用COC的方式呢?終于,想到了使用通配符。
          查看Struts2 Docs,找到相關配置方法:

          <package name="alliance" namespace="/alliance" extends="struts-default">
                  
          <action name="*/*" class="cn.zeroall.cow.web.alliance.action.{1}Action" method="{2}">
                      
          <result name="target" type="velocity">/templates/alliance/{1}/${target}.vm</result>
                      
          <result name="success" type="velocity">/templates/alliance/{1}/{2}.vm</result>
                      
          <result name="input" type="velocity">/templates/alliance/{1}/{2}.vm</result>
                      
          <result name="fail" type="velocity">/templates/common/error.vm</result>
                  
          </action>
          </package>

          恩,非常方便,可是啟動jetty,發現滿足正則的url,就是找不到Action。
          無奈,debug代碼,找到原因,需要在struts.properties中,配置:
          struts.enable.SlashesInActionNames = true
          見注釋:
          ### Set this to true if you wish to allow slashes in your action names.  If false,
          ### Actions names cannot have slashes, and will be accessible via any directory
          ### prefix.  This is the traditional behavior expected of WebWork applications.
          ### Setting to true is useful when you want to use wildcards and store values
          ### in the URL, to be extracted by wildcard patterns, such as 
          ### 
          <action name="*/*" method="{2}" class="actions.{1}"> to match "/foo/edit" or 
          ### "/foo/save".

          啟動,COC終于成功。

          但是(又冒出一個但是),針對*/*正則的url mapping,如何做validation呢?
          按照struts2的約定,是通過:
          [package/]ActionName-${配置中的action name=""中的名字}-validation.xml

          如何把"/"這個符號放入到${配置中的action name=""中的名字}呢?
          "/"可不是一個合法的文件名。

          比如,我要為AlliedMemberAction/doRegister做validation,那么約定的校驗文件名應該是:
          cn/zeroall/cow/web/alliance/action/AlliedMemberAction-AlliedMember/doRegister-validation.xml
          這個特殊符號,可難剎我也。

          無奈,繼續debug,發現在代碼:
          xwork框架中的,AnnotationActionValidatorManager:
          private  List<ValidatorConfig> buildAliasValidatorConfigs(Class aClass, String context, boolean checkFile) {
                  String fileName = aClass.getName().replace('.', '/') + "-" + context + VALIDATION_CONFIG_SUFFIX;

                  return loadFile(fileName, aClass, checkFile);
          }
          這個context就是action name=""中的url表達式。

          思想斗爭后,由于我不喜歡使用*-*的pattern,更喜歡使用*/*pattern,只好修改了源碼:
          private  List<ValidatorConfig> buildAliasValidatorConfigs(Class aClass, String context, boolean checkFile) {
                  String fileName = aClass.getName().replace('.', '/') + "-" + context.replace("/", "-") + VALIDATION_CONFIG_SUFFIX;

                  return loadFile(fileName, aClass, checkFile);
          }
          將context中的“/”變成"-"解決這個問題。

          不清楚struts2官方怎么看待這個問題。

          大家是否有更好的方案,請指教


          posted on 2009-09-26 14:06 stone2083 閱讀(3658) 評論(5)  編輯  收藏 所屬分類: java

          Feedback

          # re: Struts2.1.6--想用通配符,不容易 2009-09-27 10:16 梁章坪

          struts2的聲明式驗證的格式不是ActionName--validation.xml嗎?
          為什么在中間要加-${配置中的action name=""中的名字}?
          小弟剛剛接觸struts2。  回復  更多評論   

          # re: Struts2.1.6--想用通配符,不容易 2009-09-27 12:39 stone2083

          @梁章坪
          沒錯,最正宗的格式是ActionName--validation.xml。
          請看,AnnotationActionValidatorManager中的buildValidatorConfigs方法片段:
          validatorConfigs.addAll(buildClassValidatorConfigs(clazz, checkFile));
          在buildClassValidatorConfigs方法中,
          String fileName = aClass.getName().replace('.', '/') + VALIDATION_CONFIG_SUFFIX;
          就是你說的ActionName--validation.xml格式。
          在一個Action只有一個方法(execute)的時候,這樣是夠用的。

          但是Struts2為了支持一個Action有多個方法(CRUD)的時候,那么怎么為不同的方法尋找它需要的校驗文件呢?
          于是乎,繼續看AnnotationActionValidatorManager中的buildValidatorConfigs方法片段:
          if (context != null) {
          validatorConfigs.addAll(buildAliasValidatorConfigs(clazz, context, checkFile));
          }
          將Action名和context做組合,作為校驗文件的別名(alias)。

          至于context是什么?我一開始以為是method名,結果看了代碼,發現不是。struts2是傳了${配置中的action name=""}中的名字
          看來它的本意是希望同一個action的方法,在不同使用場景下,也允許不同的校驗規則。

          所以就有了這樣的格式定義。 :)




            回復  更多評論   

          # re: Struts2.1.6--想用通配符,不容易[未登錄] 2009-09-27 17:52 Simon

          通配符的缺陷也擺在那里

          你怎么為action配置攔截器?


          用那個插件?annotation,你越往里鉆越會發現問題多多。

          還是老老實實用XML一個個配吧。  回復  更多評論   

          # re: Struts2.1.6--想用通配符,不容易 2009-09-27 19:09 stone2083

          @Simon
          沒有放之四海而皆準的技術,任何技術,總是有利弊的,關鍵是看怎么權衡了。
          用通配符也好,zero config plugin也好,都可以,我只有一個要求,就是COC。
          做為程序員,封裝變化,抽取共性,減少一切可以減少的重復勞動力。

          在我看來,一個一個配置action,就是重復勞動力。至少在80%的場景下,配置都是差不多的。
          試想一下,當一個應用,有上千個action時,光是action的配置文件,就是幾千甚至上萬行。這個維護工作量,不敢想象。

          至于攔截器,同理,我以為,80%的情況下,action配置的攔截器都是同樣的。所以就算使用通配符,我可以用其他的方案解決特殊(20%)的需求。

          Annotation,額,這個玩意,我不敢濫用。只有20%的需求才有的特殊需求場景下,我還會考慮(僅僅是考慮)使用Annotation。
          Struts2中,Action上的annotation設計,我一直不敢恭維。所以我絕對不會使用annotation的。
          其實從我原文中,一直在描述如何尋找Validatior文件的方法,沒有說我用了annotaion。在很多場景下,我一直是xml的擁護者,當然最擁護的,是Convertion。 :)  回復  更多評論   

          # re: Struts2.1.6--想用通配符,不容易 2009-09-27 19:44 stone2083

          剛去struts官方網站溜達了下:
          http://issues.apache.org/struts/browse/WW-3024

          已經有人提交了bug,在struts2.1.8中,修復。

          查看了xwork trunk的代碼,發現修復方式,跟我原文的一樣。先這么用一段時間吧。 :)

          trunk代碼:
          http://svn.opensymphony.com/svn/xwork/trunk/core/src/main/java/com/opensymphony/xwork2/validator/AnnotationActionValidatorManager.java  回復  更多評論   

          主站蜘蛛池模板: 渭南市| 英吉沙县| 光泽县| 冷水江市| 德兴市| 黄浦区| 仪征市| 伽师县| 绍兴县| 温泉县| 天水市| 凤凰县| 秭归县| 郓城县| 昌邑市| 蒙阴县| 陆河县| 盐亭县| 安顺市| 凯里市| 东乡县| 南汇区| 高台县| 田东县| 祁门县| 民勤县| 延津县| 阿瓦提县| 龙门县| 抚州市| 武功县| 濉溪县| 织金县| 塘沽区| 原阳县| 株洲市| 玛多县| 武强县| 哈尔滨市| 铁岭县| 东乌珠穆沁旗|