本方列举了Action类中,几种配置了?@Namespace 和?@Action ?的情况,以及这些情况下如何访问Action类中的相应方法。
?
情况一:
?
class="java">@Namespace("/test") @Namespaces({ @Namespace("/test2"), @Namespace("/test3") }) @Action("/test4") @Actions({ @Action("/test5"), @Action("/test6") }) public class FileAction { public String upload() { System.out.println("uploading files..."); return "success"; } }
对于上面的这种配置,我们可以通以下的URL去调用FileAction中的upload()方法:
http://xxx.xxx.xxx.xxx:port/web工程名/test/test5!upload http://xxx.xxx.xxx.xxx:port/web工程名/test/test6!upload http://xxx.xxx.xxx.xxx:port/web工程名/test2/test5!upload http://xxx.xxx.xxx.xxx:port/web工程名/test2/test6!upload http://xxx.xxx.xxx.xxx:port/web工程名/test3/test5!upload http://xxx.xxx.xxx.xxx:port/web工程名/test3/test6!upload
?PS: 注意:@Action("/test4") ? 并未生效,因为它被@Actions({ @Action("/test5"), @Action("/test6") }) 取替了。原因。请看下面的源码:
org.apache.struts2.convention.PackageBasedActionConfigBuilder.buildConfiguration() protected void buildConfiguration(Set<Class> classes) { Map<String, PackageConfig.Builder> packageConfigs = new HashMap<String, PackageConfig.Builder>(); for (Class<?> actionClass : classes) { Actions actionsAnnotation = actionClass.getAnnotation(Actions.class); Action actionAnnotation = actionClass.getAnnotation(Action.class); .......此处省略N行代码 //if there are @Actions or @Action at the class level, create the mappings for them String methodName = hasDefaultMethod ? DEFAULT_METHOD : null; if (actionsAnnotation != null) { List<Action> actionAnnotations = checkActionsAnnotation(actionsAnnotation); for (Action actionAnnotation2 : actionAnnotations) createActionConfig(defaultPackageConfig, actionClass, defaultActionName, methodName, actionAnnotation2); } else if (actionAnnotation != null) createActionConfig(defaultPackageConfig, actionClass, defaultActionName, methodName, actionAnnotation); } } .......此处省略N行代码 } }
?从源码来看,当有@Actions注解时,@Action注解将被无视
?
大家可能会问,那?@Namespaces 会不会 覆盖?@Namespace 呢?答案是不会。原因也请看下面的源码:
org.apache.struts2.convention.PackageBasedActionConfigBuilder.determineActionNamespace() protected List<String> determineActionNamespace(Class<?> actionClass) { List<String> namespaces = new ArrayList<String>(); // Check if there is a class or package level annotation for the namespace //single namespace Namespace namespaceAnnotation = AnnotationTools.findAnnotation(actionClass, Namespace.class); if (namespaceAnnotation != null) { if (LOG.isTraceEnabled()) { LOG.trace("Using non-default action namespace from Namespace annotation of [#0]", namespaceAnnotation.value()); } namespaces.add(namespaceAnnotation.value()); } //multiple annotations Namespaces namespacesAnnotation = AnnotationTools.findAnnotation(actionClass, Namespaces.class); if (namespacesAnnotation != null) { if (LOG.isTraceEnabled()) { StringBuilder sb = new StringBuilder(); for (Namespace namespace : namespacesAnnotation.value()) sb.append(namespace.value()).append(","); sb.deleteCharAt(sb.length() - 1); LOG.trace("Using non-default action namespaces from Namespaces annotation of [#0]", sb.toString()); } for (Namespace namespace : namespacesAnnotation.value()) namespaces.add(namespace.value()); } //don't use default if there are annotations if (!namespaces.isEmpty()) return namespaces; ......此处省略N行代码 }
?从源码来看,是先读取@Namespace中的namspace,然后再读取@Namespaces中的namespace(s),将它们的值合并到一起进行返回的。
但是,一般情况下,配置了@Namespaces 或者 @Actions 时,就不会再去配置 @Namespace 或者 @Action了,谁吃饱了没事做啊 ?: )
?
转回正题,继续列出另一种配置方式:
?
情况二:
?
@Namespace("/test") @Namespaces({ @Namespace("/test2"), @Namespace("/test3") }) @Action("/test4") @Actions({ @Action("/test5"), @Action("/test6") }) public class FileAction { @Action("/test7") @Actions({ @Action("/test8"), @Action("/test9") }) public String upload() { System.out.println("uploading files..."); return "success"; } public String gotoUpload() { return "gotoUpload"; } }
?对于上面的这种配置,我们可以通以下的URL去调用FileAction中的upload()方法:
http://xxx.xxx.xxx.xxx:port/web工程名/test/test8 http://xxx.xxx.xxx.xxx:port/web工程名/test/test9 http://xxx.xxx.xxx.xxx:port/web工程名/test2/test8 http://xxx.xxx.xxx.xxx:port/web工程名/test2/test9 http://xxx.xxx.xxx.xxx:port/web工程名/test3/test8 http://xxx.xxx.xxx.xxx:port/web工程名/test3/test9 http://xxx.xxx.xxx.xxx:port/web工程名/test8 http://xxx.xxx.xxx.xxx:port/web工程名/test9 http://xxx.xxx.xxx.xxx:port/web工程名/test8 http://xxx.xxx.xxx.xxx:port/web工程名/test9 http://xxx.xxx.xxx.xxx:port/web工程名/test8 http://xxx.xxx.xxx.xxx:port/web工程名/test9
?