http://tapestry.javaeye.com/blog/36271
Tapestry中表單的提交有很多問題,刷新導致表單的重復提交、臭名昭著的dirty form warning、
顯示不友好的URL等,這些都可以使用redirect-after-postpostredirectredirectredirectPagefriendlyUrlurl
要使用這個模式,不得不提到一個ILinkT4listener:
java 代碼
?
- public?ILink?listenerMethod(Parameter?parameter);?
ILinkT4redirectILinkILinkLinkLinkLinkpage servicelinklinkexternal servicelinklink??
java 代碼
?
- @InjectObject("engine-service:page")??
- ??
- ??public?abstract?IEngineService?getPageService();??
- ??
- ???????public?ILink?getPageLink(String?pageName)?{??
- ??
- ???????????return?getPageService().getLink(false,?pageName);??
- ??
- ??}??
- ??
- ??
- ??
- ??????@InjectObject("engine-service:external")??
- ??
- ??public?abstract?IEngineService?getExternalService();??
- ??
- ???????public?ILink?getExternalLink(String?pageName,?Object[]?parameters)?{??
- ??
- ?????ExternalServiceParameter?esp?=?new?ExternalServiceParameter(pageName,??
- ??
- ????????????parameters);??
- ??
- ?????return?getExternalService().getLink(false,?esp);??
- ??
- ??}??
將上述方法放入到你的項目中自定義的MyBasePage(繼承Tapestry的BasePage)中,然后讓你的
頁面類繼承MyBasePage,這樣就可以使用上述方法了。
這樣在頁面提交時可以如下調用
java 代碼
?
- public?ILink?onDelete(Long?id){??
- ??
- ???
- ??
- ??
- ??
- ???
- ??
- return?getPageLink(getPageName());??
- ??
- }??
- ??
- 當然如果這個頁面帶參數,例如catgoryId=1,則代碼如下:??
- ??
- public?ILink?onDelete(Long?id){??
- ??
- ???
- ??
- ??
- ??
- ???
- ??
- return?getExternalLink(getPageName(),new?Object[]{categoryId});??
- ??
- ??
- }??
上述方式通過繼承來實現方法調用,感覺不是很好,我們可以利用Tapestry的易擴展特性來擴展它,
首先想到的就是注釋方式來注入,例如我想實現如下注入
java 代碼
?
- @InjectPageLink(“Home“)??
- ??
- Public?abstract?ILink?getHomeLink();??
- ??
- ???
- ??
- @InjectExternalLink(“Category“)??
- ??
- Public?abstract?ILink?getCategoryLink(Long?categoryId);??
這樣即去掉了頁面的繼承,也顯得比較直接。
首先是定義注釋類
java 代碼
?
- import?java.lang.annotation.ElementType;??
- ??
- import?java.lang.annotation.Retention;??
- ??
- import?java.lang.annotation.RetentionPolicy;??
- ??
- import?java.lang.annotation.Target;??
- ??
- ???
- ??
- @Target(?{?ElementType.METHOD?})??
- ??
- @Retention(RetentionPolicy.RUNTIME)??
- ??
- public?@interface?InjectPageLink?{??
- ??
- ????String?value();??
- ??
- }??
然后寫注釋的worker類
java 代碼
?
- import?java.lang.reflect.Method;??
- ??
- import?java.lang.reflect.Modifier;??
- ??
- ???
- ??
- import?org.apache.hivemind.ApplicationRuntimeException;??
- ??
- import?org.apache.hivemind.Location;??
- ??
- import?org.apache.hivemind.service.BodyBuilder;??
- ??
- import?org.apache.hivemind.service.MethodSignature;??
- ??
- import?org.apache.tapestry.annotations.AnnotationUtils;??
- ??
- import?org.apache.tapestry.annotations.MethodAnnotationEnhancementWorker;??
- ??
- import?org.apache.tapestry.engine.ILink;??
- ??
- import?org.apache.tapestry.enhance.EnhancementOperation;??
- ??
- import?org.apache.tapestry.spec.IComponentSpecification;??
- ??
- ???
- ??
- public?class?InjectPageLinkAnnotationWorker?implements??
- ??
- ???????MethodAnnotationEnhancementWorker?{??
- ??
- ???
- ??
- ????public?void?performEnhancement(EnhancementOperation?op,??
- ??
- ???????????IComponentSpecification?spec,?Method?method,?Location?location)?{??
- ??
- ???????if?(!method.getReturnType().equals(ILink.class))??
- ??
- ???????????throw?new?ApplicationRuntimeException(??
- ??
- ??????????????????"InjectPage?annotation?must?return?ILink");??
- ??
- ???
- ??
- ???????InjectPageLink?injectPageLink?=?method??
- ??
- ??????????????.getAnnotation(InjectPageLink.class);??
- ??
- ???
- ??
- ???????String?pageName?=?injectPageLink.value();??
- ??
- ???
- ??
- ???????BodyBuilder?builder?=?new?BodyBuilder();??
- ??
- ???
- ??
- ???????builder.begin();??
- ??
- ???????builder??
- ??
- ??????????????.addln(??
- ??
- ?????????????????????"return?getPage().getRequestCycle().getInfrastructure().getServiceMap().getService(?
- ?
- org.apache.tapestry.Tapestry.PAGE_SERVICE).getLink(false,\"{0}\");",??
- ??
- ?????????????????????pageName);??
- ??
- ???
- ??
- ???????builder.end();??
- ??
- ???
- ??
- ???????op.addMethod(Modifier.PUBLIC,?new?MethodSignature(method),?builder??
- ??
- ??????????????.toString(),?location);??
- ??
- ???
- ??
- ???????if?(isGetter(method))??
- ??
- ???????????op.claimReadonlyProperty(AnnotationUtils.getPropertyName(method));??
- ??
- ????}??
- ??
- ???
- ??
- ????boolean?isGetter(Method?method)?{??
- ??
- ???????return?method.getName().startsWith("get")??
- ??
- ??????????????&&?method.getParameterTypes().length?==?0;??
- ??
- ????}??
- ??
- }??
External的同樣兩個類
java 代碼
?
- import?java.lang.annotation.ElementType;??
- ??
- import?java.lang.annotation.Retention;??
- ??
- import?java.lang.annotation.RetentionPolicy;??
- ??
- import?java.lang.annotation.Target;??
- ??
- ???
- ??
- @Target(?{?ElementType.METHOD?})??
- ??
- @Retention(RetentionPolicy.RUNTIME)??
- ??
- public?@interface?InjectExternalLink?{??
- ??
- ????String?value();??
- ??
- }??
Work類
java 代碼
?
- import?java.lang.reflect.Method;??
- ??
- import?java.lang.reflect.Modifier;??
- ??
- ???
- ??
- import?org.apache.hivemind.ApplicationRuntimeException;??
- ??
- import?org.apache.hivemind.Location;??
- ??
- import?org.apache.hivemind.service.BodyBuilder;??
- ??
- import?org.apache.hivemind.service.MethodSignature;??
- ??
- import?org.apache.tapestry.Tapestry;??
- ??
- import?org.apache.tapestry.annotations.AnnotationUtils;??
- ??
- import?org.apache.tapestry.annotations.MethodAnnotationEnhancementWorker;??
- ??
- import?org.apache.tapestry.engine.ILink;??
- ??
- import?org.apache.tapestry.enhance.EnhancementOperation;??
- ??
- import?org.apache.tapestry.spec.IComponentSpecification;??
- ??
- ???
- ??
- public?class?InjectExternalLinkAnnotationWorker?implements??
- ??
- ???????MethodAnnotationEnhancementWorker?{??
- ??
- ???
- ??
- ????public?void?performEnhancement(EnhancementOperation?op,??
- ??
- ???????????IComponentSpecification?spec,?Method?method,?Location?location)?{??
- ??
- ???????if?(!method.getReturnType().equals(ILink.class))??
- ??
- ???????????throw?new?ApplicationRuntimeException(??
- ??
- ??????????????????"injectExternalLink?annotation?must?return?ILink");??
- ??
- ???
- ??
- ???????InjectExternalLink?injectExternalLink?=?method??
- ??
- ??????????????.getAnnotation(InjectExternalLink.class);??
- ??
- ???
- ??
- ???????String?pageName?=?injectExternalLink.value();??
- ??
- ???
- ??
- ???????BodyBuilder?builder?=?new?BodyBuilder();??
- ??
- ???
- ??
- ???????builder.begin();??
- ??
- ???
- ??
- ???????Class[]?parameterTypes?=?method.getParameterTypes();??
- ??
- ???????int?paramCount?=?Tapestry.size(parameterTypes);??
- ??
- ???
- ??
- ???????if?(paramCount?>?0)?{??
- ??
- ???????????if?(parameterTypes[0].isArray())?{??
- ??
- ??????????????builder??
- ??
- ?????????????????????.addln(??
- ??
- ????????????????????????????"return?getPage().getRequestCycle().getInfrastructure().getServiceMap().?
- ?
- getService(org.apache.tapestry.Tapestry.EXTERNAL_SERVICE).getLink(false,?new?org.apache.tapestry.engine.ExternalServiceParameter(\"{0}\",$1));",??
- ??
- ????????????????????????????pageName);??
- ??
- }?else?{??
- ??
- ??????????????builder??
- ??
- ?????????????????????.addln(??
- ??
- ????????????????????????????"java.lang.Object[]?params?=?new?java.lang.Object[{0}];",??
- ??
- ????????????????????????????paramCount);??
- ??
- ??????????????for?(int?i?=?0;?i?<?paramCount;?i++)?{??
- ??
- ??????????????????builder.add("params[{0}]?=?",?i);??
- ??
- ???
- ??
- ??????????????????if?(parameterTypes[i].isPrimitive())??
- ??
- ?????????????????????builder.add("($w)?");??
- ??
- ???
- ??
- ????????????????????
- ??
- ???
- ??
- ??????????????????builder.addln("${0};",?i?+?1);??
- ??
- ??????????????}??
- ??
- ??????????????builder??
- ??
- ?????????????????????.addln(??
- ??
- ????????????????????????????"return?getPage().getRequestCycle().getInfrastructure().getServiceMap().getService(org.apache.tapestry.Tapestry.EXTERNAL_SERVICE).getLink(false,?new?org.apache.tapestry.engine.ExternalServiceParameter(\"{0}\",params));",??
- ??
- ????????????????????????????pageName);??
- ??
- ???????????}??
- ??
- ???????}??
- ??
- ???
- ??
- ???????builder.end();??
- ??
- ???
- ??
- ???????op.addMethod(Modifier.PUBLIC,?new?MethodSignature(method),?builder??
- ??
- ??????????????.toString(),?location);??
- ??
- ???
- ??
- ???????if?(isGetter(method))??
- ??
- ???????????op.claimReadonlyProperty(AnnotationUtils.getPropertyName(method));??
- ??
- ????}??
- ??
- ???
- ??
- ????boolean?isGetter(Method?method)?{??
- ??
- ?????????
- ??
- ???
- ??
- ???????return?method.getName().startsWith("get")??
- ??
- ??????????????&&?method.getParameterTypes().length?==?0;??
- ??
- ????}??
- ??
- }??
類寫好了,然后就是貢獻到Tapestry中
xml 代碼
?
- <module?id="your.model.annotation"?version="1.0.0"?package="your.package.annotations">??
- ??
- ?????<contribution?configuration-id="tapestry.annotation.MethodWorkers">??
- ??
- ??????<worker?annotation="InjectPageLink"?object="instance:InjectPageLinkAnnotationWorker"/>??
- ??
- ??????<worker?annotation="InjectExternalLink"?object="instance:InjectExternalLinkAnnotationWorker"/>??
- ??
- ????<!--</span-->contribution>??
- ??
- <!--</span-->module>??
好了將你的module放入項目hivemodule.Xml作為子module。
Ok,enjoy it!
?
Tapestry中表單的提交有很多問題,刷新導致表單的重復提交、臭名昭著的dirty form warning、 顯示不友好的URL等,這些都可以使用redirect-after-postpostredirectredirectredirectPagefriendlyUrlurl 要使用這個模式,不得不提到一個ILinkT4listener: java 代碼 ? - public?ILink?listenerMethod(Parameter?parameter);?
ILinkT4redirectILinkILinkLinkLinkLinkpage servicelinklinkexternal servicelinklink??
java 代碼 ? - @InjectObject("engine-service:page")??
- ??
- ??public?abstract?IEngineService?getPageService();??
- ??
- ???????public?ILink?getPageLink(String?pageName)?{??
- ??
- ???????????return?getPageService().getLink(false,?pageName);??
- ??
- ??}??
- ??
- ??
- ??
- ??????@InjectObject("engine-service:external")??
- ??
- ??public?abstract?IEngineService?getExternalService();??
- ??
- ???????public?ILink?getExternalLink(String?pageName,?Object[]?parameters)?{??
- ??
- ?????ExternalServiceParameter?esp?=?new?ExternalServiceParameter(pageName,??
- ??
- ????????????parameters);??
- ??
- ?????return?getExternalService().getLink(false,?esp);??
- ??
- ??}??
將上述方法放入到你的項目中自定義的MyBasePage(繼承Tapestry的BasePage)中,然后讓你的 頁面類繼承MyBasePage,這樣就可以使用上述方法了。 這樣在頁面提交時可以如下調用 java 代碼 ? - public?ILink?onDelete(Long?id){??
- ??
- ???
- ??
- ??
- ??
- ???
- ??
- return?getPageLink(getPageName());??
- ??
- }??
- ??
- 當然如果這個頁面帶參數,例如catgoryId=1,則代碼如下:??
- ??
- public?ILink?onDelete(Long?id){??
- ??
- ???
- ??
- ??
- ??
- ???
- ??
- return?getExternalLink(getPageName(),new?Object[]{categoryId});??
- ??
- ??
- }??
上述方式通過繼承來實現方法調用,感覺不是很好,我們可以利用Tapestry的易擴展特性來擴展它, 首先想到的就是注釋方式來注入,例如我想實現如下注入 java 代碼 ? - @InjectPageLink(“Home“)??
- ??
- Public?abstract?ILink?getHomeLink();??
- ??
- ???
- ??
- @InjectExternalLink(“Category“)??
- ??
- Public?abstract?ILink?getCategoryLink(Long?categoryId);??
這樣即去掉了頁面的繼承,也顯得比較直接。 首先是定義注釋類 java 代碼 ? - import?java.lang.annotation.ElementType;??
- ??
- import?java.lang.annotation.Retention;??
- ??
- import?java.lang.annotation.RetentionPolicy;??
- ??
- import?java.lang.annotation.Target;??
- ??
- ???
- ??
- @Target(?{?ElementType.METHOD?})??
- ??
- @Retention(RetentionPolicy.RUNTIME)??
- ??
- public?@interface?InjectPageLink?{??
- ??
- ????String?value();??
- ??
- }??
然后寫注釋的worker類
java 代碼 ? - import?java.lang.reflect.Method;??
- ??
- import?java.lang.reflect.Modifier;??
- ??
- ???
- ??
- import?org.apache.hivemind.ApplicationRuntimeException;??
- ??
- import?org.apache.hivemind.Location;??
- ??
- import?org.apache.hivemind.service.BodyBuilder;??
- ??
- import?org.apache.hivemind.service.MethodSignature;??
- ??
- import?org.apache.tapestry.annotations.AnnotationUtils;??
- ??
- import?org.apache.tapestry.annotations.MethodAnnotationEnhancementWorker;??
- ??
- import?org.apache.tapestry.engine.ILink;??
- ??
- import?org.apache.tapestry.enhance.EnhancementOperation;??
- ??
- import?org.apache.tapestry.spec.IComponentSpecification;??
- ??
- ???
- ??
- public?class?InjectPageLinkAnnotationWorker?implements??
- ??
- ???????MethodAnnotationEnhancementWorker?{??
- ??
- ???
- ??
- ????public?void?performEnhancement(EnhancementOperation?op,??
- ??
- ???????????IComponentSpecification?spec,?Method?method,?Location?location)?{??
- ??
- ???????if?(!method.getReturnType().equals(ILink.class))??
- ??
- ???????????throw?new?ApplicationRuntimeException(??
- ??
- ??????????????????"InjectPage?annotation?must?return?ILink");??
- ??
- ???
- ??
- ???????InjectPageLink?injectPageLink?=?method??
- ??
- ??????????????.getAnnotation(InjectPageLink.class);??
- ??
- ???
- ??
- ???????String?pageName?=?injectPageLink.value();??
- ??
- ???
- ??
- ???????BodyBuilder?builder?=?new?BodyBuilder();??
- ??
- ???
- ??
- ???????builder.begin();??
- ??
- ???????builder??
- ??
- ??????????????.addln(??
- ??
- ?????????????????????"return?getPage().getRequestCycle().getInfrastructure().getServiceMap().getService(?
- ?
- org.apache.tapestry.Tapestry.PAGE_SERVICE).getLink(false,\"{0}\");",??
- ??
- ?????????????????????pageName);??
- ??
- ???
- ??
- ???????builder.end();??
- ??
- ???
- ??
- ???????op.addMethod(Modifier.PUBLIC,?new?MethodSignature(method),?builder??
- ??
- ??????????????.toString(),?location);??
- ??
- ???
- ??
- ???????if?(isGetter(method))??
- ??
- ???????????op.claimReadonlyProperty(AnnotationUtils.getPropertyName(method));??
- ??
- ????}??
- ??
- ???
- ??
- ????boolean?isGetter(Method?method)?{??
- ??
- ???????return?method.getName().startsWith("get")??
- ??
- ??????????????&&?method.getParameterTypes().length?==?0;??
- ??
- ????}??
- ??
- }??
External的同樣兩個類
java 代碼 ? - import?java.lang.annotation.ElementType;??
- ??
- import?java.lang.annotation.Retention;??
- ??
- import?java.lang.annotation.RetentionPolicy;??
- ??
- import?java.lang.annotation.Target;??
- ??
- ???
- ??
- @Target(?{?ElementType.METHOD?})??
- ??
- @Retention(RetentionPolicy.RUNTIME)??
- ??
- public?@interface?InjectExternalLink?{??
- ??
- ????String?value();??
- ??
- }??
Work類
java 代碼 ? - import?java.lang.reflect.Method;??
- ??
- import?java.lang.reflect.Modifier;??
- ??
- ???
- ??
- import?org.apache.hivemind.ApplicationRuntimeException;??
- ??
- import?org.apache.hivemind.Location;??
- ??
- import?org.apache.hivemind.service.BodyBuilder;??
- ??
- import?org.apache.hivemind.service.MethodSignature;??
- ??
- import?org.apache.tapestry.Tapestry;??
- ??
- import?org.apache.tapestry.annotations.AnnotationUtils;??
- ??
- import?org.apache.tapestry.annotations.MethodAnnotationEnhancementWorker;??
- ??
- import?org.apache.tapestry.engine.ILink;??
- ??
- import?org.apache.tapestry.enhance.EnhancementOperation;??
- ??
- import?org.apache.tapestry.spec.IComponentSpecification;??
- ??
- ???
- ??
- public?class?InjectExternalLinkAnnotationWorker?implements??
- ??
- ???????MethodAnnotationEnhancementWorker?{??
- ??
- ???
- ??
- ????public?void?performEnhancement(EnhancementOperation?op,??
- ??
- ???????????IComponentSpecification?spec,?Method?method,?Location?location)?{??
- ??
- ???????if?(!method.getReturnType().equals(ILink.class))??
- ??
- ???????????throw?new?ApplicationRuntimeException(??
- ??
- ??????????????????"injectExternalLink?annotation?must?return?ILink");??
- ??
- ???
- ??
- ???????InjectExternalLink?injectExternalLink?=?method??
- ??
- ??????????????.getAnnotation(InjectExternalLink.class);??
- ??
- ???
- ??
- ???????String?pageName?=?injectExternalLink.value();??
- ??
- ???
- ??
- ???????BodyBuilder?builder?=?new?BodyBuilder();??
- ??
- ???
- ??
- ???????builder.begin();??
- ??
- ???
- ??
- ???????Class[]?parameterTypes?=?method.getParameterTypes();??
- ??
- ???????int?paramCount?=?Tapestry.size(parameterTypes);??
- ??
- ???
- ??
- ???????if?(paramCount?>?0)?{??
- ??
- ???????????if?(parameterTypes[0].isArray())?{??
- ??
- ??????????????builder??
- ??
- ?????????????????????.addln(??
- ??
- ????????????????????????????"return?getPage().getRequestCycle().getInfrastructure().getServiceMap().?
- ?
- getService(org.apache.tapestry.Tapestry.EXTERNAL_SERVICE).getLink(false,?new?org.apache.tapestry.engine.ExternalServiceParameter(\"{0}\",$1));",??
- ??
- ????????????????????????????pageName);??
- ??
- }?else?{??
- ??
- ??????????????builder??
- ??
- ?????????????????????.addln(??
- ??
- ????????????????????????????"java.lang.Object[]?params?=?new?java.lang.Object[{0}];",??
- ??
- ????????????????????????????paramCount);??
- ??
- ??????????????for?(int?i?=?0;?i?<?paramCount;?i++)?{??
- ??
- ??????????????????builder.add("params[{0}]?=?",?i);??
- ??
- ???
- ??
- ??????????????????if?(parameterTypes[i].isPrimitive())??
- ??
- ?????????????????????builder.add("($w)?");??
- ??
- ???
- ??
- ????????????????????
- ??
- ???
- ??
- ??????????????????builder.addln("${0};",?i?+?1);??
- ??
- ??????????????}??
- ??
- ??????????????builder??
- ??
- ?????????????????????.addln(??
- ??
- ????????????????????????????"return?getPage().getRequestCycle().getInfrastructure().getServiceMap().getService(org.apache.tapestry.Tapestry.EXTERNAL_SERVICE).getLink(false,?new?org.apache.tapestry.engine.ExternalServiceParameter(\"{0}\",params));",??
- ??
- ????????????????????????????pageName);??
- ??
- ???????????}??
- ??
- ???????}??
- ??
- ???
- ??
- ???????builder.end();??
- ??
- ???
- ??
- ???????op.addMethod(Modifier.PUBLIC,?new?MethodSignature(method),?builder??
- ??
- ??????????????.toString(),?location);??
- ??
- ???
- ??
- ???????if?(isGetter(method))??
- ??
- ???????????op.claimReadonlyProperty(AnnotationUtils.getPropertyName(method));??
- ??
- ????}??
- ??
- ???
- ??
- ????boolean?isGetter(Method?method)?{??
- ??
- ?????????
- ??
- ???
- ??
- ???????return?method.getName().startsWith("get")??
- ??
- ??????????????&&?method.getParameterTypes().length?==?0;??
- ??
- ????}??
- ??
- }??
類寫好了,然后就是貢獻到Tapestry中 xml 代碼 ? - <module?id="your.model.annotation"?version="1.0.0"?package="your.package.annotations">??
- ??
- ?????<contribution?configuration-id="tapestry.annotation.MethodWorkers">??
- ??
- ??????<worker?annotation="InjectPageLink"?object="instance:InjectPageLinkAnnotationWorker"/>??
- ??
- ??????<worker?annotation="InjectExternalLink"?object="instance:InjectExternalLinkAnnotationWorker"/>??
- ??
- ????<!--</span-->contribution>??
- ??
- <!--</span-->module>??
好了將你的module放入項目hivemodule.Xml作為子module。 Ok,enjoy it!
?
|
是呀,tapestry的經典處理流程就是get page->set state->active
active調用的是forward方法,就是當前頁面的實際頁面與url上指示的頁面不相符,這也無可厚非。tapestry如果真的要完全的OO的話,屏蔽URL上的處理是必須的。
取得ILink來redirect的一個好處是可以防止form提交后refresh。 |
Tapestry中表單的提交有很多問題,刷新導致表單的重復提交、臭名昭著的dirty form warning、
顯示不友好的URL等,這些都可以使用redirect-after-postpostredirectredirectredirectPagefriendlyUrlurl
要使用這個模式,不得不提到一個ILinkT4listener:
java 代碼
?
- public?ILink?listenerMethod(Parameter?parameter);?
ILinkT4redirectILinkILinkLinkLinkLinkpage servicelinklinkexternal servicelinklink??
java 代碼
?
- @InjectObject("engine-service:page")??
- ??
- ??public?abstract?IEngineService?getPageService();??
- ??
- ???????public?ILink?getPageLink(String?pageName)?{??
- ??
- ???????????return?getPageService().getLink(false,?pageName);??
- ??
- ??}??
- ??
- ??
- ??
- ??????@InjectObject("engine-service:external")??
- ??
- ??public?abstract?IEngineService?getExternalService();??
- ??
- ???????public?ILink?getExternalLink(String?pageName,?Object[]?parameters)?{??
- ??
- ?????ExternalServiceParameter?esp?=?new?ExternalServiceParameter(pageName,??
- ??
- ????????????parameters);??
- ??
- ?????return?getExternalService().getLink(false,?esp);??
- ??
- ??}??
將上述方法放入到你的項目中自定義的MyBasePage(繼承Tapestry的BasePage)中,然后讓你的
頁面類繼承MyBasePage,這樣就可以使用上述方法了。
這樣在頁面提交時可以如下調用
java 代碼
?
- public?ILink?onDelete(Long?id){??
- ??
- ???
- ??
- ??
- ??
- ???
- ??
- return?getPageLink(getPageName());??
- ??
- }??
- ??
- 當然如果這個頁面帶參數,例如catgoryId=1,則代碼如下:??
- ??
- public?ILink?onDelete(Long?id){??
- ??
- ???
- ??
- ??
- ??
- ???
- ??
- return?getExternalLink(getPageName(),new?Object[]{categoryId});??
- ??
- ??
- }??
上述方式通過繼承來實現方法調用,感覺不是很好,我們可以利用Tapestry的易擴展特性來擴展它,
首先想到的就是注釋方式來注入,例如我想實現如下注入
java 代碼
?
- @InjectPageLink(“Home“)??
- ??
- Public?abstract?ILink?getHomeLink();??
- ??
- ???
- ??
- @InjectExternalLink(“Category“)??
- ??
- Public?abstract?ILink?getCategoryLink(Long?categoryId);??
這樣即去掉了頁面的繼承,也顯得比較直接。
首先是定義注釋類
java 代碼
?
- import?java.lang.annotation.ElementType;??
- ??
- import?java.lang.annotation.Retention;??
- ??
- import?java.lang.annotation.RetentionPolicy;??
- ??
- import?java.lang.annotation.Target;??
- ??
- ???
- ??
- @Target(?{?ElementType.METHOD?})??
- ??
- @Retention(RetentionPolicy.RUNTIME)??
- ??
- public?@interface?InjectPageLink?{??
- ??
- ????String?value();??
- ??
- }??
然后寫注釋的worker類
java 代碼
?
- import?java.lang.reflect.Method;??
- ??
- import?java.lang.reflect.Modifier;??
- ??
- ???
- ??
- import?org.apache.hivemind.ApplicationRuntimeException;??
- ??
- import?org.apache.hivemind.Location;??
- ??
- import?org.apache.hivemind.service.BodyBuilder;??
- ??
- import?org.apache.hivemind.service.MethodSignature;??
- ??
- import?org.apache.tapestry.annotations.AnnotationUtils;??
- ??
- import?org.apache.tapestry.annotations.MethodAnnotationEnhancementWorker;??
- ??
- import?org.apache.tapestry.engine.ILink;??
- ??
- import?org.apache.tapestry.enhance.EnhancementOperation;??
- ??
- import?org.apache.tapestry.spec.IComponentSpecification;??
- ??
- ???
- ??
- public?class?InjectPageLinkAnnotationWorker?implements??
- ??
- ???????MethodAnnotationEnhancementWorker?{??
- ??
- ???
- ??
- ????public?void?performEnhancement(EnhancementOperation?op,??
- ??
- ???????????IComponentSpecification?spec,?Method?method,?Location?location)?{??
- ??
- ???????if?(!method.getReturnType().equals(ILink.class))??
- ??
- ???????????throw?new?ApplicationRuntimeException(??
- ??
- ??????????????????"InjectPage?annotation?must?return?ILink");??
- ??
- ???
- ??
- ???????InjectPageLink?injectPageLink?=?method??
- ??
- ??????????????.getAnnotation(InjectPageLink.class);??
- ??
- ???
- ??
- ???????String?pageName?=?injectPageLink.value();??
- ??
- ???
- ??
- ???????BodyBuilder?builder?=?new?BodyBuilder();??
- ??
- ???
- ??
- ???????builder.begin();??
- ??
- ???????builder??
- ??
- ??????????????.addln(??
- ??
- ?????????????????????"return?getPage().getRequestCycle().getInfrastructure().getServiceMap().getService(?
- ?
- org.apache.tapestry.Tapestry.PAGE_SERVICE).getLink(false,\"{0}\");",??
- ??
- ?????????????????????pageName);??
- ??
- ???
- ??
- ???????builder.end();??
- ??
- ???
- ??
- ???????op.addMethod(Modifier.PUBLIC,?new?MethodSignature(method),?builder??
- ??
- ??????????????.toString(),?location);??
- ??
- ???
- ??
- ???????if?(isGetter(method))??
- ??
- ???????????op.claimReadonlyProperty(AnnotationUtils.getPropertyName(method));??
- ??
- ????}??
- ??
- ???
- ??
- ????boolean?isGetter(Method?method)?{??
- ??
- ???????return?method.getName().startsWith("get")??
- ??
- ??????????????&&?method.getParameterTypes().length?==?0;??
- ??
- ????}??
- ??
- }??
External的同樣兩個類
java 代碼
?
- import?java.lang.annotation.ElementType;??
- ??
- import?java.lang.annotation.Retention;??
- ??
- import?java.lang.annotation.RetentionPolicy;??
- ??
- import?java.lang.annotation.Target;??
- ??
- ???
- ??
- @Target(?{?ElementType.METHOD?})??
- ??
- @Retention(RetentionPolicy.RUNTIME)??
- ??
- public?@interface?InjectExternalLink?{??
- ??
- ????String?value();??
- ??
- }??
Work類
java 代碼
?
- import?java.lang.reflect.Method;??
- ??
- import?java.lang.reflect.Modifier;??
- ??
- ???
- ??
- import?org.apache.hivemind.ApplicationRuntimeException;??
- ??
- import?org.apache.hivemind.Location;??
- ??
- import?org.apache.hivemind.service.BodyBuilder;??
- ??
- import?org.apache.hivemind.service.MethodSignature;??
- ??
- import?org.apache.tapestry.Tapestry;??
- ??
- import?org.apache.tapestry.annotations.AnnotationUtils;??
- ??
- import?org.apache.tapestry.annotations.MethodAnnotationEnhancementWorker;??
- ??
- import?org.apache.tapestry.engine.ILink;??
- ??
- import?org.apache.tapestry.enhance.EnhancementOperation;??
- ??
- import?org.apache.tapestry.spec.IComponentSpecification;??
- ??
- ???
- ??
- public?class?InjectExternalLinkAnnotationWorker?implements??
- ??
- ???????MethodAnnotationEnhancementWorker?{??
- ??
- ???
- ??
- ????public?void?performEnhancement(EnhancementOperation?op,??
- ??
- ???????????IComponentSpecification?spec,?Method?method,?Location?location)?{??
- ??
- ???????if?(!method.getReturnType().equals(ILink.class))??
- ??
- ???????????throw?new?ApplicationRuntimeException(??
- ??
- ??????????????????"injectExternalLink?annotation?must?return?ILink");??
- ??
- ???
- ??
- ???????InjectExternalLink?injectExternalLink?=?method??
- ??
- ??????????????.getAnnotation(InjectExternalLink.class);??
- ??
- ???
- ??
- ???????String?pageName?=?injectExternalLink.value();??
- ??
- ???
- ??
- ???????BodyBuilder?builder?=?new?BodyBuilder();??
- ??
- ???
- ??
- ???????builder.begin();??
- ??
- ???
- ??
- ???????Class[]?parameterTypes?=?method.getParameterTypes();??
- ??
- ???????int?paramCount?=?Tapestry.size(parameterTypes);??
- ??
- ???
- ??
- ???????if?(paramCount?>?0)?{??
- ??
- ???????????if?(parameterTypes[0].isArray())?{??
- ??
- ??????????????builder??
- ??
- ?????????????????????.addln(??
- ??
- ????????????????????????????"return?getPage().getRequestCycle().getInfrastructure().getServiceMap().?
- ?
- getService(org.apache.tapestry.Tapestry.EXTERNAL_SERVICE).getLink(false,?new?org.apache.tapestry.engine.ExternalServiceParameter(\"{0}\",$1));",??
- ??
- ????????????????????????????pageName);??
- ??
- }?else?{??
- ??
- ??????????????builder??
- ??
- ?????????????????????.addln(??
- ??
- ????????????????????????????"java.lang.Object[]?params?=?new?java.lang.Object[{0}];",??
- ??
- ????????????????????????????paramCount);??
- ??
- ??????????????for?(int?i?=?0;?i?<?paramCount;?i++)?{??
- ??
- ??????????????????builder.add("params[{0}]?=?",?i);??
- ??
- ???
- ??
- ??????????????????if?(parameterTypes[i].isPrimitive())??
- ??
- ?????????????????????builder.add("($w)?");??
- ??
- ???
- ??
- ????????????????????
- ??
- ???
- ??
- ??????????????????builder.addln("${0};",?i?+?1);??
- ??
- ??????????????}??
- ??
- ??????????????builder??
- ??
- ?????????????????????.addln(??
- ??
- ????????????????????????????"return?getPage().getRequestCycle().getInfrastructure().getServiceMap().getService(org.apache.tapestry.Tapestry.EXTERNAL_SERVICE).getLink(false,?new?org.apache.tapestry.engine.ExternalServiceParameter(\"{0}\",params));",??
- ??
- ????????????????????????????pageName);??
- ??
- ???????????}??
- ??
- ???????}??
- ??
- ???
- ??
- ???????builder.end();??
- ??
- ???
- ??
- ???????op.addMethod(Modifier.PUBLIC,?new?MethodSignature(method),?builder??
- ??
- ??????????????.toString(),?location);??
- ??
- ???
- ??
- ???????if?(isGetter(method))??
- ??
- ???????????op.claimReadonlyProperty(AnnotationUtils.getPropertyName(method));??
- ??
- ????}??
- ??
- ???
- ??
- ????boolean?isGetter(Method?method)?{??
- ??
- ?????????
- ??
- ???
- ??
- ???????return?method.getName().startsWith("get")??
- ??
- ??????????????&&?method.getParameterTypes().length?==?0;??
- ??
- ????}??
- ??
- }??
類寫好了,然后就是貢獻到Tapestry中
xml 代碼
?
- <module?id="your.model.annotation"?version="1.0.0"?package="your.package.annotations">??
- ??
- ?????<contribution?configuration-id="tapestry.annotation.MethodWorkers">??
- ??
- ??????<worker?annotation="InjectPageLink"?object="instance:InjectPageLinkAnnotationWorker"/>??
- ??
- ??????<worker?annotation="InjectExternalLink"?object="instance:InjectExternalLinkAnnotationWorker"/>??
- ??
- ????<contribution>??
- ??
- <module>??
好了將你的module放入項目hivemodule.Xml作為子module。
Ok,enjoy it!