`
Rainbow702
  • 浏览: 1065229 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类

struts2 中,@NameSpace 和 @Action 的使用示例

阅读更多

本方列举了Action类中,几种配置了 @Namespace 和 @Action  的情况,以及这些情况下如何访问Action类中的相应方法。

 

情况一:

 

@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

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics