前一篇博文已经用实例展现了Strut2零配置是怎样使用的,以及与传统Struts2配置文件的区别。本篇博文主要来Struts2的零配置约定的规则。
JaveEE的框架大多使用配置的方式来实现一些功能。使用配置文件有很多弊端,如无法进行编译检查,随着开发的进行,配置文件日趋臃肿,那么配置文件的加载就成了问题。于是诞生了新思想—约定优于配置。
约定大于配置即实现约定一个规范,大家按照这个规范去开发而不用灵活配置一些东西,这样从某种程度上提高了程序的开发效率。“零”配置并不是说没有配置文件,而是不在配置文件中对Action进行配置,有些基本的常量配置还需要在配置文件中进行。
一、三个常量
1、视图默认存放位置
convention插件会自动到/WEB-INF/content目录中查找结果页,这个值可以通过在struts.xml或者struts.properties文件中设置struts.convention.result.path这个属性的值来改变到其他路径。示例如下:
这样就将默认的result页面路径设置到了WEB-INF/mypage文件夹里面。
2、Action类存放位置
在应用启动的时候,Convention插件会自动搜索位于action、actions、struts、struts2的包及其子包下的所有Java类,以搜索Action类。
可以通过在struts.xml或者struts.properties文件中设置struts.convention.package.locators这个属性的值来改变搜索的文件夹。示例如下:
3、指定过滤类
struts.Convention.exclude.packges:指定不扫描哪些包下的java类,位于这些包结构下的java类将不会自动映射成Action;
二、约定
1、视图结果约定
通常Action方法返回一个字符串,通过返回的字符串找到结果页面,而使用Convention插件允许我们在action代码中指定和返回字符串不同的结果页面。
2、映射Action的名称的规则:
(1) 如果该Action类名以Action作为后缀,那么会将后缀的Action去掉,其他的不做处理。
(2) 如果该Action类名采用驼峰式的写法,也就是每个单词首字母大写的写法,那么需要把所有字母变成小写,单词与单词之间以中"-"隔开。
public class DrawmsgAction{
public String delete() throws Exception {
if (ids != null) {
drawmsgManager.deleteEntityById(ids);
}
return "delete";
}
}
访问的URL为:…/drawmsg!delete.action 视图地址:WEB-INF/content/drawmg-delete.jsp
默认情况下,Convention插件总会到WEB-INF/content路径下定位jsp,定位资源的约定是:actionName+result+suffix.当某个逻辑后视图找不到对应的jsp时,Convention插件会自动试图使用actionName+suffix作为物理资源。
例如:com.bjpower.user.LoginAction类,返回success字符串时,Convention将优先考虑使用WEB-INF/content/user/login-success.jsp作为视图资源,如果找不到,WEB-INF/content/user/login.jsp也可作为对应的视图资源。
三、注解
1、通过@Action注释
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport {
@Action("action1")
public String method1() {
return add;
}
@Action("/user/action2")
public String method2() {
return delete;
}
}
使用@Action注释后,只是多了一种调用方式,而不是说覆盖了原来的调用方式。如
public class UserAction extends ActionSupport {
@Action("/another/url")
public String method1() {
return “error”;
}
我们调用method1方法可以通过两种方式:
/user!method1.action 映射url:/WEB-INF/content/user-error.jsp
/another/url!method1.action 映射url:/WEB-INF/content/another/url-error.jsp
区别:两种调用的映射是不一样的,所以,可以灵活跳转到不同页面。
2、通过@Namespace
@Namespace("/other")
public class UserWorld extends ActionSupport {
public String method1() {
return “add”;
}
@Action("url")
public String method2() {
return “delete”;
}
@Action("/different/url")
public String method3() {
return “modify”;
}
}
通过/other/user-world!method1.action访问method1 方法。
通过/other/url!method2.action 访问method2 方法
通过 /different /url!method3.action 访问method3方法
与@Action注释不同的是,该注释覆盖了默认的namespace(这里是’/’),此时再用user!method1.action已经不能访问method1 了.
3、@Results和@Result
全局的(global)。
全局results可以被action类中所有的action分享,这种results在action类上使用注解进行声明。
@Results({
@Result(name="toList", location="/WEB-INF/tolist.jsp")
})
public class UserAction extends ActionSupport {
public String method1() {
return “add”;
}
@Action("/different/url")
public String method2() {
return “delete”;
}
}
访问 /user!method1.action 时,返回 /WEB-INF/user-tolist.jsp
访问 /user!method2.action 时,返回 /WEB-INF/user-tolist.jsp
访问/different/url!method2.action 时,返回 /WEB-INF/user-tolist.jsp
本地的(local)
本地results只能在action方法上进行声明。
public class UserAction extends ActionSupport {
@Action(value="/other/method",results={@Result(name = "error", location = "www.baidu.com",type="redirect")})
public String method1() {
return “add”;
}
}
调用 /user!method1.action 时,返回 /WEB-INF/content/user-add.jsp
调用/other/method!method1.action时,返回www.baidu.com
4、Action之间相互转发
开发的时候,有时候在一个Action方法执行完毕之后,不是直接返回视图,而是跳转到另外一个Action上,而且还需要传递请求参数。
@Results({
@Result(name = "tolist", location = "${ctx}/draw/drawmsg!list.action?funmenuId=${funmenuId}&types=${types}", type = "redirect"),
})
public class DrawmsgAction extends CRUDActionSupport {
//删除成功后直接返回列表界面
public String delete() throws Exception {
if (ids != null) {
drawmsgManager.deleteEntityById(ids);
}
return "tolist";
}
//项目信息列表信息
public String list() throws Exception {
Return list;
}
}
小结:
如上所述,Struts2用注解来实现零配置。只是将配置从XML格式换成了注解方式,并不是真的零配置。以上只是简单的介绍了约定优于配置,还在逐步学习中。