Struts2引入Convention插件来支持零配置。
在项目下加入struts2-convention-plugin-2.3.16.3.jar包
Action的搜索和映射约定如下:
对于Convention插件而言,它会自动搜索位于action、actions、struts、struts2包下的所有Java类,Convention插件会把如下两种java类当成Action处理。
1)、所有实现com.opensymphony.xwork2.Action类的java类。
2)、所有类名以Action结尾的Java类。
下面的这些类是符合Convention插件的java类:
org.crazyit.app.actions.LoginAction
org.crazyit.app.actions.books.getBooks
org.crazyit.app.action.LoginAction
org.crazyit.app.struts.auction.bid.BidAction
org.crazyit.app.struts2.wage.hr.AddEmployeeAction
Struts2的Convention允许设置如下三个常量:
1)、struts.convention.exclude.packages:指定不扫描哪些包下的java类。
2)、struts.convention.package.locators:Convention插件使用该常量指定包作为搜寻Action的根包。
对于action.lee.LoginAction类,按照约定原本应该映射到/lee/login;如果将该常量设置为lee,则
该Action将会映射到/login
3)、struts.convention.action.packages:Convention插件以该常量作为根包来搜索action类。
Convention除了扫描action、actions、struts、struts2包下的类外,还会扫描该常量指定的一个
或包,从中发现action类。
找到合适的Action类后,Convention插件会按照约定部署这些Action.部署Action时,action、actions、 struts、struts2会被映射成根命名空间,而这些包的子包则被映射成对应的命名空间。如下:
org.crazyit.app.actions.LoginAction 映射到根命名空间 /
org.crazyit.app.actions.books.getBooks 映射到/books/命名空间
org.crazyit.app.action.LoginAction 映射到根命名空间 /
org.crazyit.app.struts.auction.bid.BidAction 映射到/auction/bid/命名空间
org.crazyit.app.struts2.wage.hr.AddEmployeeAction 映射到/wage/hr/命名空间
Action的name属性根据该Action的类名映射,遵循以下规则:
1)、如果该Action类名包含Action后缀,将该Action类名的Action后缀去掉。否则不做处理。
2)、将Action类名的驼峰写法(每个单子的首字母大写,其它字母小写)转换成中划线写法。
如下:
org.crazyit.app.actions.LoginAction 映射到/login.action
org.crazyit.app.actions.books.getBooks 映射到/books/get-books.action
org.crazyit.app.action.LoginAction 映射到/login.action
org.crazyit.app.struts.auction.bid.BidAction 映射到/aution/bid/bid.action
org.crazyit.app.struts2.wage.hr.AddEmployeeAction映射到/wage/hr/add-employee.action
示例程序如下:
package org.crazyit.app.action.user;
public class LoginAction extends ActionSupport{
private String username;
private String password;
//省略setter和getter方法
public String execute() throws Exception{
if(getUsername().equals("admin") && getPassword().equals("password"){
return SUCCESS;
}
return ERROR;
}
}
该Action被映射到如下URL:/user/login
定义如下form,将会提交到LoginAction处理。
<s:form action="user/login“>
...........
</s:form>
Result约定:
Action处理用户请求后返回一个字符串作为逻辑视图,该逻辑视图映射到实际的物理视图才有意义。Convention默认为逻辑视图和物理视图之间提供了约定。
默认请情况下Convention总会到Web应用的WEB-INF/content路径下定位物理资源。定位的约定是actionName+resultCode+suffix,当某个逻辑视图找不到对应的物理视图资源时,Convention会自动使用actionName+suffix作为物理视图资源。
例如:org.crazyit.app.action.user.LoginAction返回success字符串,Convention优先考虑使用WEB-INF/content/user/目录下的login-success.jsp作为视图资源,如果找到不文件,login.jsp也可作为对应的视图资源。
Action链的约定
如果希望一个Action处理结束后不是进入另外一个视图界面,而是进入另外一个Action形成Action链,则通过Convention查询,遵循以下三个约定即可:
1)、第一个Action返回的逻辑视图的字符串没有对应的视图资源。
2)、第二个Action与第一个Action处于同一包下。
3)、第二个Action映射的URL为:firstactionName+resultcod
例如,希望org.crazyit.app.action.FirstAction处理结束后进入第二个Action继续处理。下面先看第一个Action的代码:
程序清单 :FirstAction
package org.crazyit.app.action;
public class FirstAction extends ActionSupport{
public String execute(){
System.out.println("进入第一个Action“);
addActionMessage("第一个Action的提示信息");
return "second";
}
}
为了让该Action处理用户请求后进入第二个Action,而不是进入视图页面,因此该应用WEB-INF/content下不能提供first-second.jsp或second.jsp
第二个Action的映射URL应该是first-second,因此第二个Action的类名应该是FirstSecond.下面是第二个Action的代码.
package org.crazyit.app.action;
public class FirstSecondAction Extends ActionSupport{
public String execute(){
System.out.println("进入第二个Action“);
addActionMessage("第二个Action的提示信息");
return "SUCCESS";--------------------------------------------------------------------------------------------------------------------
struts2的Convention插件主要集中管理Action和Result映射之上。而Struts2的配置文件处理管理Action、result外,还需要管理拦截器、异常处理等相关信息。Convention使用"约定“来管理这些配置。除此之外,convention还运行使用注解管理Action和Result管理,从而覆盖Convention的约定。