原文地址
从 struts2.1 版本开始, Convention Plugin 作为替换替换 Codebehind Plugin 来实现 Struts2 的零配置。 零配置并不是没有配置,而是通过约定大于配置的方式,大量通过约定来调度页面的跳转而使得配置大大减少 ,我们也可以在类中复写其中的方法来达到扩展的目的。
使用 Convention 插件,需要将其 JAR 文件放到你应用的 WEB-INF/lib 目录中,你也可以在你 maven项目的 POM 文件中添加下面包依赖
convention-plugin的约定
1. 默认情况下,Convention会默认所有的结果页面都存储在WEB-INF/content下,你也可以在struts的配置文件中设定struts.convention.result.path的值到一个新的路径。如
这样的话所有结果页面的会存储在 WEB-INF/page 下了,把 jsp 放在 WEB-INF 下有一个好处 ,别人就没有办法直接访问了,这样就可以简化 spring security 的配置工作。
2. 默认 情况下, 包 的 路径包含 action,actions,struts,struts2 的所有包都会被 struts 作为含有 Action 类的路径来搜索。你可以通过设置 struts.convention.package.locators 属性来修改这个配置,如 springside 的 struts.xml 中是这样配置的,
则在项目中,包 的 路径 含有 web的将被视为Action存在的路径来进行搜索。
3. 接着, Convention 从前一步找到的 package 以及其子 package 中寻找 com.opensymphony.xwork2.Action 的实现以及以 Action 结尾的类,如:
com.courseonline.test.web.account.UserAction 就会被扫描到。
4. 命名空间。从定义的 .package.locators 标示开始到包结束的部分,就是命名空间。举个例子 ,上面我们定义了
所以 com.courseonline.test.web.account.UserAction的命名空间是: “ / account ” 。
5. Convention 通过如下规则确定 URL 的具体资源部分 : 去掉类名的 Action 部分。然后将每个分部的首字母转为小写,用‘ - ’分割,你可以设置 struts.convention.action.name.separator 如
比如上面的例子 com.courseonline.test.web.account.UserAction 对应的 jsp 为 /WEB-INF/content/account/use.jsp
如果是 com.courseonline.test.web.account.User Detail Action 对应的 jsp 为 /WEB-INF/content/account/use-detail.jsp
下面是 convention 的一些常用注解
1.@Action 注解
未用 @Action 注解前
默认调用路径 |
访问方法 |
默认映射路径 |
/user!method1.action |
method1 |
/WEB-INF/content/user.jsp |
/user!method2.action |
method2 |
/WEB-INF/content/user.jsp |
|
|
|
使用 @Action 注解后
@Action 注解后调用的路径 |
访问方法 |
@Action 注解后映射的路径 |
/url1!method1.action |
method1 |
/WEB-INF/content/url1.jsp |
/account/url2!method2.action |
method2 |
/WEB-INF/content/account/url2.jsp |
2. @Namespace 注释
调用路径 |
访问方法 |
映射路径 |
/account/user-detail!method1.acton |
method1 |
/WEN-INF/content/account/user-detail-error.jsp |
/account/url!method2.acton |
method2 |
/WEN-INF/content/account/url.jsp |
/different/url2!method3.action |
method3 |
/WEN-INF/content/different/url2.jsp |
与@Action 注释不同的是,该注释覆盖了默认的namespace( 默认的 是’/’),此时再用 user-detail !method1.action已经不能 访问 method1 了 .
3. @Result
Convention 允许action类为每个action定义不同的results,results分为两类,全局的(global)和本地的(local),全局results可以被action类中所有的action分享,这种results在action类上使用注解进行声明。本地results只能在action方法上进行声明。下面是两种results注解的例子 .
1 )全局的 (global)。
调用路径 |
访问方法 |
映射路径 |
/user!method1.action |
method1 |
/WEB-INF/fail.jsp |
/different/url!method2.action |
method2 |
/WEB-INF/fail.jsp |
2 本地的(local)。
调用路径 |
访问方法 |
映射路径 |
/user!method1.action |
method1 |
/WEB-INF/content/user-error.jsp |
/other/url!method2.action |
method1 |
/WEB-INF/fail.jsp |
有了上面的知识,现在来看看 springside 3 的 mini-web 项目中部分用到的 convention 插件的地方,理解起来就不难了。
比较典型的是 UserAction.java 。
这里我只选了三个返回结果分别为 SUCCESS 、 INPUT 、和 RELOAD 的方法来做例子。
调用路径 |
访问方法 |
映射路径 |
/account/user!list.action |
list |
/WEB-INF/content/account/user.jsp |
/account/user!input.action |
input |
/WEB-INF/content/account/user-input.jsp |
/account/user!save.action |
save |
/WEB-INF/content/account/user.jsp |
在调用 save 方法后,为什么会返回 /WEB-INF/content/account/user.jsp 这个页面 呢?因为在全局的 Result 定义名为reload的result重定向到user.action, 其他result则按照convention默认 ,所以当调用完 save 方法后,返回的是RELOAD ,又被重定向到 user.action ,然后返回到 /WEB-INF/content/account/user.jsp 了;同理,访问 input 方法时,返回的是 INPUT ,所以会返回 /WEB-INF/content/account/user-input.jsp
@Namespace("/account") 表示 定义URL映射对应/account/user.action
@Results( { @Result(name = CrudActionSupport.RELOAD, location = "user.action", type = "redirect") })
定义名为reload的result重定向到user.action, 其他result则按照convention默认.
参考资料: http://www.blogjava.net/libin2722/articles/256525.html