struts2零配置详解(struts-Convention-plugin)

来源:互联网 发布:上海数据恢复公司排名 编辑:程序博客网 时间:2024/06/03 17:43

struts2.1开始,struts2不再推荐使用Codebehind作为零配置插件,而是改为使用Convention插件来支持零配置,Codebehind相比,Convention插件更彻底,该插件完全抛弃配置信息,不仅不需要是使用struts.xml文件进行配置,甚至不需要使用Annotation进行配置,而是由struts2根据约定自动配置。零配置并不是没有配置,而是通过约定大于配置的方式,大量通过约定来调度页面的跳转而使得配置大大减少。所以,首先应该了解下convention-plugin的约定:

      <!--设置Convention插件定位视图资源的根路径,默认为/WEB-INFO/content -->      <constant name="struts.convention.result.path" value="/WEB-INF/content/"/>      <!--如果设置为false,则可以将视图页面放置Action对应的目录(无需放入WEB-INFO/content) -->      <constant name="struts.convention.result.flatLayout" value="true"/>      <!--Convention搜索Action类的类名后缀,默认为Action -->      <constant name="struts.convention.action.suffix" value="Action"/>      <!--是否禁止通过包扫描Action,默认是false -->      <constant name="struts.convention.action.disableScanning" value="false"/>      <!--设置即使没有@Action注释,是否依然创建Action映射。默认值为false -->Create action mappings, even if no @Action is found      <constant name="struts.convention.action.mapAllMatches" value="false"/>      <!--设置是否所有实现com.opensymphony.xwork2.Action的Action都创建Action映射,默认是true -->      <constant name="struts.convention.action.checkImplementsAction" value="true"/>      <!--设置Convention映射的Action所在包的默认父包。默认值是convention-default -->      <constant name="struts.convention.default.parent.package" value="convention-default"/>      <!--设置映射Action时,是否将Action的name属性值转换为所有字母小写,默认值是true -->      <constant name="struts.convention.action.name.lowercase" value="true"/>      <!--设置映射Action时指定name属性值各单词之间的分隔符。默认值为中画线(“-”) -->      <constant name="struts.convention.action.name.separator" value="-"/>      <!--默认包路径包含action,actions,struts,struts2的所有包都会被struts作为含有Action类的路径来搜索 -->      <constant name="struts.convention.package.locators" value="action,actions,struts,struts2"/>      <!--指定禁止从Action的根包里搜索Action。默认值为false -->      <constant name="struts.convention.package.locators.disable" value="false"/>      <!--如果指定了该常量,Convention只会以该常量值开始的包中搜索Action类 -->      <constant name="struts.convention.package.locators.basePackage" value=""/>      <!--指定排除在搜索Action之外的包。默认值为org.hibernate.* ... -->      <constant name="struts.convention.exclude.packages" value="org.apache.struts.*,org.apache.struts2.*,org.springframework.web.struts.*,org.springframework.web.struts2.*,org.hibernate.*"/>      <!--指定Convention映射的Result时默认支持的结果类型。默认值为dispatcher,velocity,freemarker -->      <constant name="struts.convention.relative.result.types" value="dispatcher,velocity,freemarker"/>      <!--设置是否重定向到斜线(/)。例如用户请求/foo,但/foo不存在时,如果设置该常量为可重定向到/foo/。默认值是true -->      <constant name="struts.convention.redirect.to.slash" value="true"/>

下面开始了解一下Convention如何使用

1.struts-Convention-plugin-2.1.6.jar文件复制到WEB-INF/lib路径下

2. struts-Convention-plugin如何扫描我们的Action类的呢

1)对于Convention插件而言,它会自动搜索位于actionactionsstrutsstruts2包下的所有java类,对于所有实现了com.opensymphony.xwork2.Actionjava类以及所有类名以Action结尾的java类都会当成Action类来处理。

<constant name="struts.convention.package.locators" value="action,actions,struts,struts2"/>可以通过设置struts.convention.package.locators属性来修改这个配置。如:<constant name="struts.convention.package.locators" value="web,action" /> 

则定义了在项目中,包路径包含web和action的将被视为Action存在的路径来进行搜索。
Com.ustb.web.* 或者 com.ustb.action.*都将被视为含有Action的包路径而被搜索。
2)struts.Convention.exclude.packges::指定不扫描哪些包下的java类,位于这些包结构下的java类将不会自动映射成Action
3) struts.convention.action.packages:Convention插件以该常量指定包作为根包来搜索Action类。Convention插件除了扫描action,actions,struts,struts2四个包的类以外,还会扫描该常量指定的一个或多个包,Convention会试图从中发现Action类。

4)   struts.convention.package.locators.basePackag: 扫描的基包,也即是,只有这个包的子包才被Struts2 Convention Plugin扫描。

4. 映射Actionname时,遵循如下两步规则:

1)  如果该Action类名包含Action后缀,将该Action类名的Action后缀去掉。否则不做任何处理。
2)  Action类名的驼峰写法(每个单词首字母大写、其他字母小写的写法)转成中画线写法(所有字母小写,单词与单词之间以中画线隔开)
如:LoginAction映射的Acionname属性为loginGetBooks映射的Actionname的属性为get-booksAddEmployeeAction映射的Actionname属性为add-employee

5. Convention如何确定URL的具体资源

  1)  默认情况下,Convention总会到WEB应用的WEB-INF/content路径下定位物理资源,定位资源的约定是:actionRUL+resultCODE+suffix。当某个逻辑视图找不到对应的试图资源时,Convention会自动视图使用ActionURL+suffix作为物理视图资源。

       如:actions.fore.LoginAction 返回success字符串时,Convention优先考虑使用WEB-INF/content/fore目录下的login-success.jsp作为视图资源。如果找不到该文件,login.jsp也可作为对应的试图资源。如果返回input字符串,Convention会将WEB-INF/content/fore里面查找login-input.jsp

       2)  去掉类名的Action部分,然后将将每个分部的首字母转为小写,用’-’分割。
      如:UserAction->user  UserDetailAction ->user-detail。结合上面的。对于com.ustb.web.user.detail.UserDetailAction,映射的 url就是/WEB-INF/content/user/detail/user-detail.jsp

3)struts支持.jsp .html .htm .vm格式的文件。下面是actiong和结果模版的映射关系:

URLResult 
File that could matchResult Type/hellosuccess/WEB-INF/content/hello.jspDispatcher/hellosuccess/WEB-INF/content/hello-success.htmDispatcher/hellosuccess/WEB-INF/content/hello.ftlFreeMarker/hello-worldinput/WEB-INF/content/hello-world-input.vmVelocity/test1/test2/helloerror/WEB-INF/content/test/test2/hello-error.htmlDispatcher

 

 

 

 

 

 

 

当然,简单的通过默认的方式来进行配置不能完全满足实际项目的需要。所幸,convention的零配置是非常灵活的。

通过@Action注释 
对如下例子:

  1. package com.example.web;   
  2.   
  3. import com.opensymphony.xwork2.Action;   
  4. import com.opensymphony.xwork2.ActionSupport;    
  5.   
  6. public class HelloAction extends ActionSupport {   
  7.     @Action("action1")   
  8.     public String method1() {   
  9.         return SUCCESS;   
  10.     }   
  11.   
  12.     @Action("/user/action2")   
  13.     public String method2() {   
  14.         return SUCCESS;   
  15.     }   
  16. }  
方法名默认调用路径默认映射路径method1/hello!method1.action ./WEB-INF/content/hello.jspmethod2/hello!method2.action./WEB-INF/content/hello.jsp

通过@Action注释后

方法名@Action注释后调用路径@Action注释 后映射路径method1/action1!method1.action./WEB-INF/content/action1.jspmethod1/user/action2!method2.action/WEB-INF/content/user/action2.jsp


通过@Actions注释

  1. package com.example.web;   
  2.   
  3. import com.opensymphony.xwork2.ActionSupport;    
  4. import org.apache.struts2.convention.annotation.Action;   
  5. import org.apache.struts2.convention.annotation.Actions;   
  6.   
  7. public class HelloAction extends ActionSupport {   
  8.   @Actions({   
  9.     @Action("/different/url"),   
  10.     @Action("/another/url")   
  11.   })   
  12.   public String method1() {   
  13.     return “error”;   
  14.   }  

我们可以通过:/different/url!method1.action  /another/url!method1.action 来调用method1 方法。
对应的映射路径分别是/WEB-INF/content/different/url-error.jsp; /WEB-INF/content/another/url-error.jsp 

可能误导了大家,一个方法被@Action注释后,只是多了一种调用方式,而不是说覆盖了原来的调用方式。比如对于如下例子:

  1. package com.example.web;   
  2.   
  3. import com.opensymphony.xwork2.ActionSupport;    
  4. import org.apache.struts2.convention.annotation.Action;   
  5. import org.apache.struts2.convention.annotation.Actions;   
  6.   
  7. public class HelloAction extends ActionSupport {   
  8.   @Action("/another/url")   
  9.   public String method1() {   
  10.     return “error”;   
  11.   }  

我们调用method1方法可以通过两种方式:
 /hello!method1.action 映射 url:/WEB-INF/content/hello-error.jsp 
2
 /another/url!method1.action 映射 url:/WEB-INF/content/another/url-error.jsp 
可见,两种方式均可对method1方法进行调用,唯一的区别就是,两种调用的映射是不一样的,所以,想跳转到不同的界面,这是一个非常好的选择。


通过@Namespace 注释

  1. package com.example.web;   
  2.   
  3. import com.opensymphony.xwork2.ActionSupport;    
  4. import org.apache.struts2.convention.annotation.Action;   
  5. import org.apache.struts2.convention.annotation.Actions;   
  6. @Namespace("/other")   
  7. public class HelloWorld extends ActionSupport {   
  8.   
  9.   public String method1() {   
  10.     return “error”;   
  11.   }   
  12.     @Action("url")   
  13.   public String method2() {   
  14. return “error”;   
  15.   }   
  16.   
  17.     @Action("/different/url")   
  18.   public String method3() {   
  19. return “error”;   
  20.   }   
  21. }  


通过 /other/hello-world!method1.action 访问method1 方法。
通过
 /other/url!method2.action 访问method2 方法
通过
 /different /url!method3.action 访问method3 方法 
与@Action 注释不同的是,该注释覆盖了默认的namespace(这里是’/’),此时再用hello!method1.action 已经不能访问method1 了.
@Results和@Result 
1 全局的(global)。
 
全局results可以被action类中所有的action分享,这种results在action类上使用注解进行声明。

  1. package com.example.actions;   
  2.   
  3. import com.opensymphony.xwork2.ActionSupport;    
  4. import org.apache.struts2.convention.annotation.Action;   
  5. import org.apache.struts2.convention.annotation.Actions;   
  6. import org.apache.struts2.convention.annotation.Result;   
  7. import org.apache.struts2.convention.annotation.Results;   
  8.   
  9. @Results({   
  10.   @Result(name="failure", location="/WEB-INF/fail.jsp")   
  11. })   
  12. public class HelloWorld extends ActionSupport {   
  13.   public String method1() {   
  14.     return “failure”;   
  15.   }   
  16.     @Action("/different/url")   
  17.   public String method2() {   
  18.     return “failure”;   
  19.   }   
  20.   
  21. }  

当我们访问 /hello -world !method1.action 时,返回 /WEB-INF/fail.jsp 
当我们访问 /hello 
-world 
!method2.action 时,返回 /WEB-INF/fail.jsp 
当我们访问 /different/url!method2.action 时,返回 /WEB-INF/fail.jsp 


2 本地的(local)。 
本地results只能在action方法上进行声明。

  1. package com.example.actions;   
  2.   
  3. import com.opensymphony.xwork2.ActionSupport;    
  4. import org.apache.struts2.convention.annotation.Action;   
  5. import org.apache.struts2.convention.annotation.Actions;   
  6. import org.apache.struts2.convention.annotation.Result;   
  7. import org.apache.struts2.convention.annotation.Results;   
  8.   
  9. public class HelloWorld extends ActionSupport {   
  10.     @Action(value="/other/bar",results={@Result(name = "error", location = "www.baidu.com",type="redirect")})   
  11.   public String method1() {   
  12.     return “error”;   
  13.   }   
  14. }  

原创粉丝点击