struts2是的配置文件是struts.xml,可以将Action的URL映射和结果放在该文件中,也可以通过Convention Plugin支持注解方式来配置URL映射和结果。
使用时需要把Convention Plugin添加到classpath中;如果是maven工程则添加依赖:
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>2.3.15.1</version>
</dependency>
Convention Plugin:顾名思义,就是一种约定的插件。用户按照约定编写代码即可。
一、Convention Plugin约定:
1. 包扫描
包路径包含action,actions,struts,struts2的所有包都会被struts当作含有Action类的路径来搜索,可以更改:
<constant name="struts.convention.package.locators" value="struts2,action" />
2. 类匹配
从包扫描找到的package及其子package寻找com.opensymphony.xwork2.Action的实现类或后缀为Action的类:如:
// 包名包含locators指定的struts2,会被扫描到;后缀名为Action,符合条件
com.john.struts2.FantasticAction
// 包名包含locators指定的action,会被扫描到;实现了Action接口,符合条件
com.john.action.FabulousController implements com.opensymphony.xwork2.Action
// 包名不包含locators指定的名称,不会被当作Action处理
com.john.mystruts.SignificantAction
3. 命名空间
命名空间就是URL中上下文和Action之间的部分,如http://localhost:8080/vehicle/car/buy.action,这里的命名空间就是/car
和SpringMVC通过类和方法的@RequestMapping注解来定义命名空间不同,struts2的命名空间默认是locators标示到包结束的部分:
// 这里的locators为struts2,同时也为包的结尾,命名空间为 /
com.john.struts2.FantasticAction
// locators为struts2,后面还有car,所以命名空间为 /car
com.john.struts2.car.QuickBuyAction
注:如果包路径包含一个以上的locators,以第一个作为标示,其余的作为命名空间的组成部分。如:
// 命名空间为/action/car,这里的action虽然也是locators,但前面已经有struts2了
com.john.struts2.action.car.QuickBuyAction
4. Action映射URL约定
去掉类名中的Action部分,然后将其它部分(每个都以大写开头)转换为小写,之间默认以'-'连接,可以通过下面常量更改分隔符:
<constant name="struts.convention.action.name.separator" value="-" />
如QuickBuyAction,去掉Action后,为QuickBuy,以大写字母,分成两个部分:Quick, Buy,转换成小写后,再以'-'连接,即为:quick-buy
通过上面的几个步骤,能够根据类的全限定名确定访问URL。以下URL省略主机名、端口和上下文,后缀为.do
// 访问URL为:/action/car/quick-buy.action
com.john.struts2.action.car.QuickBuyAction
5. 结果模板页存放路径
默认在/WEB-INF/content下,可以通过下面的常量配置:
<constant name="struts.convention.result.path" value="/WEB-INF/jsp/" />
当执行下面的execute方法时:
a. struts2会到path+命名空间(/WEB-INF/jsp/action/car)的路径下优先寻找 去除Action后缀之后,以separator标志('-')分隔的小写类名(quick-buy)-视图名称(success).文件扩展名(jsp)的文件。
b. 没有则试着搜寻前半部分(quick-buy.jsp)。
c. 再没有则搜索后半部分(success.jsp),还没有就报
404错误。
注:
文件路径包含命名空间
package com.john.struts2.action.car;
public class QuickBuyAction{
// 通过/action/car/quick-buy!execute.do或/action/car/quick-buy.do(execute是默认方法,可省略)访问
public String execute() throws Exception {
return "success";
}
}
6. 支持模板文件
struts2支持.html, .htm, .vm, .ftl, .jsp格式的文件,以下为映射:
URL |
Result |
File that could match |
Result Type |
/hello |
success |
/WEB-INF/content/hello.jsp |
Dispatcher |
/hello |
success |
/WEB-INF/content/hello-success.htm |
Dispatcher |
/hello |
success |
/WEB-INF/content/hello.ftl |
FreeMarker |
/hello-world |
input |
/WEB-INF/content/hello-world-input.vm |
Velocity |
/test1/test2/hello |
error |
/WEB-INF/content/test/test2/hello-error.html |
Dispatcher |
二、注解配置
有时候约定不能满足项目需要,Convention Plugin通过以下几个注解来实现自定义配置:
1. @Namespace
标注在Action类上,
覆盖约定的命名空间。
package com.john.struts2.action.myns;
import org.apache.struts2.convention.annotation.Namespace;
//import org.apache.struts2.convention.annotation.ParentPackage;
import com.opensymphony.xwork2.ActionSupport;
@Namespace("/open")
public class MyAction extends ActionSupport {
public String execute() throws Exception {
return "error";
}
}
未加@Namespace前:
方法名 |
默认调用路径 |
默认映射路径 |
execute |
/action/myns/my!execute.do |
/WEB-INF/content/action/myns/my-error.jsp |
添加@Namespace后,可以看出,
调用和映射路径中的命名空间都被覆盖了:
方法名 |
@Namespace注解后调用路径 |
@Namespace注解后映射路径 |
execute |
/open/my!execute.do |
/WEB-INF/content/open/my-error.jsp |
注:此时访问/action/myns/my.do(不经过方法),还是能找到/WEB-INF/content/action/myns/my.jsp
2. @Action和@Actions
将URL映射到指定方法,
扩展约定配置
package com.john.struts2.action;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
import com.opensymphony.xwork2.ActionSupport;
public class KittyAction extends ActionSupport {
@Action("action1")
public String acid() {
return SUCCESS;
}
@Action("/user/action2")
public String sweet() {
return SUCCESS;
}
@Action("/autumn/summer/action3")
public String bitter() {
return SUCCESS;
}
@Actions({ @Action("/one/url"), @Action("/another/url") })
public String pungent() {
return SUCCESS;
}
}
未加@Action前:
方法名 |
默认调用路径 |
默认映射路径 |
acid |
/action/kitty!acid.do |
/WEB-INF/content/action/kitty-success.jsp |
sweet |
/action/kitty!sweet.do |
/WEB-INF/content/action/kitty-success.jsp |
bitter |
/action/kitty!bitter.do |
/WEB-INF/content/action/kitty-success.jsp |
pungent |
/action/kitty!pungent.do |
/WEB-INF/content/action/kitty-success.jsp |
添加@Action后,在上面的基础上
扩展新的调用和映射路径:
方法名 |
@Action后调用路径 |
@Action后映射路径 |
acid |
/action/action1!acid.do |
/WEB-INF/content/action/action1-success.jsp |
sweet |
/user/action2!sweet.do |
/WEB-INF/content/user/action2-success.jsp |
bitter |
/autumn/summer/action3!bitter.do |
/WEB-INF/content/autumn/summer/action3-success.jsp |
pungent |
/one/url!pungent.do |
/WEB-INF/content/one/url-success.jsp |
pungent |
/another/url!pungent.do |
/WEB-INF/content/another/url-success.jsp |
注:
i. @Action
标注在方法上,却是对
类名映射路径的扩展。上面的KittyAction约定映射是kitty,同时也可以是@Action指定的映射,如/action1
ii. @Action
不会覆盖原来的约定配置,如标注了@Action的acid方法,通过/kitty!acid还是可以访问的。
iii. @Action的值如果包含一个以上的路径分隔符(/),会用
第一个路径子串替代默认命名空间,之后的路径子串替代Action类的约定映射,如:
@Action("/user/action2"),/user替代/action,/action2替代kitty
@Action("/autumn/summer/action3"),/autumn替代action,/summer/action3替代kitty
iv. @Actions是@Action的数组形式,可以将
多个URL和一个方法关联
3. @Results和@Result
类级别(global)
标注在Action类上,结果映射可以被action类的所有方法共享。
package com.john.struts2.action;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import com.opensymphony.xwork2.ActionSupport;
// @Result(name = "enjoyable", location = "/WEB-INF/enjoyable.jsp")
@Results({ @Result(name = "enjoyable", location = "/WEB-INF/enjoyable.jsp") })
public class NationalDay extends ActionSupport {
public String travel() {
return "enjoyable";
}
@Action("/cozy/fragrant")
public String home() {
return "enjoyable";
}
@Action(value = "/happy/blessing", results = { @Result(name = "happiness", location = "/WEB-INF/conjugal.jsp", type = "dispatcher") })
public String wedding() {
return "happiness";
}
}
方法名 |
调用路径 |
返回视图 |
travel |
/action/national-day!travel.do |
/WEB-INF/enjoyable.jsp |
home |
/action/national-day!home.do |
/WEB-INF/enjoyable.jsp |
home |
/cozy/fragrant!home.do |
/WEB-INF/enjoyable.jsp |
方法级别(local)
以@Action的results属性呈现,结果映射只能由被标注方法所用。
方法名 |
调用路径 |
返回视图 |
wedding |
/action/national-day!wedding.do |
/WEB-INF/content/action/national-day-happiness.jsp |
wedding |
/happy/blessing!wedding.do |
/WEB-INF/conjugal.jsp |