struts实现零配置

来源:互联网 发布:网络架构师英语怎么说 编辑:程序博客网 时间:2024/05/01 06:36

一、约定大于配置

从struts2.1开始,struts2不再推荐使用Codebehind作为零配置插件,而是改为使用Convention插件来支持零配置,和Codebehind相比,Convention插件更彻底,该插件完全抛弃配置信息,不仅不需要是使用struts.xml文件进行配置,甚至不需要使用Annotation进行配置,而是由struts2根据约定自动配置。

使用Convention:
1. 将struts-Convention-plugin-2.1.6.jar文件复制到WEB-INF/lib路径下
2. 对于Convention插件而言,它会自动搜索位于action,actions,struts,struts2包下的所有java类,Convention插件会把如下两种java类当成Action处理:
      2.1、 所有实现了com.opensymphony.xwork2.Action的java类
      2.2、 所有类名以Action结尾的java类
3. Convention插件还允许设置如下三个常量:
      3.1、 struts.Convention.exclude.packges:指定不扫描哪些包下的java类,位于这些包结构下的java类将不会自动映射成Action;
      3.2、 struts.convention.package.locators:Convention插件使用该常量指定的包作为搜寻Action的根包。对于actions.fore.LoginAction类,按约定原本应映射到/fore/login;如果将该常量设为fore,则该Action将会映射到/login
      3.3、 struts.convention.action.packages:Convention插件以该常量指定包作为根包来搜索Action类。Convention插件除了扫描action,actions,struts,struts2四个包的类以外,还会扫描该常量指定的一个或多个包,Convention会试图从中发现Action类。
注意:struts.convention.package.locators和struts.convention.action.packages两个常量的作用比较微妙,开发者在利用这两个常量时务必小心。
如下面Action所在包被映射的命名空间如下:
                 com.example.actions.MainAction ->映射 /
                 com.example.actions.products.Display -> 映射 /products
                 com.example.struts.company.details.ShowCompanyDetailsAction ->映射  /company/details
4. 映射Action的name时,遵循如下两步规则:
     4.1、 如果该Action类名包含Action后缀,将该Action类名的Action后缀去掉。否则不做任何处理。
     4.2、 将Action类名的驼峰写法(每个单词首字母大写、其他字母小写的写法)转成中画线写法(所有字母小写,单词与单词之间以中画线隔开)
如:LoginAction映射的Acion的name属性为login,GetBooks映射的Action的name的属性为get-books,AddEmployeeAction映射的Action的name属性为add-employee
5. 默认情况下。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
6. 为了看到struts2应用里的Action等各种资源的影射情况,struts2提供了Config Browser插件。使用方法,将struts2-config-browser-plugin-2.1.6.jar文件复制到struts2应用的WEB-INF\lib目录中。
打开首页地址:http://localhost:8080/applicationName/config-browser/actionNames.action这里可以看到Config Browser插件的首页。
注意:这里不管开发者是否使用struts.xml文件进行配置,一样可以看到struts的配置信息。
7.Action链的约定
如果希望一个Action处理结束后不是进入一个试图页面,而是进行另一个Action形成的Action链。通过Convention插件则只需遵守如下三个约定即可。
      7.1、 第一个Action返回的逻辑视图字符串没有对应的视图资源

      7.2、 第二个Action与第一个Action处在同一个包下

      7.3、 第二个Action影射的URL为:firstActionURL+“-”+resultCODE

如:
[java] view plaincopy
  1. package com.example.actions;  
  2.   
  3. import com.opensymphony.xwork2.Action;  
  4. import com.opensymphony.xwork2.ActionSupport;  
  5.   
  6. public class HelloAction extends ActionSupport {  
  7.     @Action("foo")  
  8.     public String foo() {  
  9.         return "bar";  
  10.     }  
  11.   
  12.     @Action("foo-bar")  
  13.     public String bar() {  
  14.         return SUCCESS;  
  15.     }  
  16. }  

注意:由于Convention插件根据Action和jsp页面来动态生成映射的,因此不管是Acion的改变,还是JSP页面的改变都需要Convention插件重新加载映射。那么只要我们为struts2应用配置如下两个常量就可以了。
                  <!--配置struts2应用于开发模式--!>
                  <constant name=”struts.devMode” value=”true”/>
                  <!—配置Convention插件自动重加载映射--!>
                  <constant name=”struts.convention.classes.reload” value=”true”/>
几个重要的常量:
struts.convention.action.disableJarScanning---是否从包中搜索Action
struts.convention.action.package--------Convention插件以该常量指定包作为根包
struts.convention.result.path ---设置Convention插件定位视图资源的根路径。默认值为/WEB-INF/content

struts.convention.result.flatLayout—如果是为false则可以将试图放置Action对应的目录下,无需放入WEB-INF/content

二、Convention注解

1. Convention的Annotation
        1.1、 与Action相关的两个Annotation是@Action 和@Actions
        1.2、@Action中可指定一个value属性。类似于指定<action name=””/>属性值
        1.3、@Action中还可以指定一个params属性,该属性是一个字符串数组,用于该Acion指定的参数名和参数值。params属性应遵守如下格式:{“name1”,”value1”,”name2”,”value2”}
       1.4、 @Actions 也用于修饰Action类里的方法,用于将该方法映射到多个URL.@Actions用于组织多个@Action.因此它可将一个方法映射成多个逻辑Action。
如:
[java] view plaincopy
  1. private String message;  
  2.   
  3. public String getMessage() {  
  4.     return message;  
  5. }  
  6.   
  7. public void setMessage(String message) {  
  8.   
  9.     this.message = message;  
  10. }  
  11.   
  12. @Actions({ @Action(value = "login1", params = { "message""指定Result!" }),  
  13.         @Action(value = "login2") })  
  14. public String login() {  
  15.     return "str";  
  16. }  
  17.   
  18. @Action(value = "other")  
  19. public String abc() {  
  20.     return "abc";  
  21. }  
我们可以通过/login1.action访问,而在访问时,message这个属性已经有值,为message=”指定Result!” 返回的视图是login1-str.jsp;
当我们用/login2.action访问时,str的值为null。返回的视图为 login2-str.jsp;
而我们通过/other.action调用的是abc()方法,返回的视图为/other-abc.jsp;
2. @Result 和@Results、@ResultPath 
       2.1、@Result 和@Results
                 2.1.1、@Results用于组织多个@Result因此它只需指定一个value属性值,该value属性值为多个@Result

                 2.1.2、@Result相当于struts.xml文件的<result/>元素。使用@Result必须指定一个name属性,相当于<result name=””/>。

                 2.1.3、@Result可选的属性:

                             ① type 相当于<result type=””/>指定返回视图资源的类型

                             ② location 相当于<result>…..</result>中间部分,用于指定实际视图位置
                             ② params:该属性相当于<result/>元素里多个<param../>子元素的作用,用于为该Result指定参数值。该属性应满足{“name1”,”value1”,”name2”,”value2”}格式
                2.1.4、@Result有以下两种用法:
① Action级的Result映射:以@Actions组合多个@Action后修饰的Action类。这种Result映射对该Action里的所有方法都有效。
②方法级Result映射:将多个@Result组成数组后作为@Action的results属性值。这种Result映射仅对被修饰的方法有效。
[java] view plaincopy
  1. @Results({ @Result(name = "failure", location = "fail.jsp") })  
  2. public class HelloWorld extends ActionSupport {  
  3.     @Action(value = "/different/url", results = { @Result(name = "success", location = "http://struts.apache.org", type = "redirect") })  
  4.     public String execute() {  
  5.         return SUCCESS;  
  6.     }  
  7.   
  8.     @Action("/another/url")  
  9.     public String doSomething() {  
  10.         return SUCCESS;  
  11.     }  
  12. }  
       2.1、@ResultPath则用于修饰包和Action类,用于改变被修饰Action所对应的物理视图资源的根路径。例如:默认情况下,Convention都会到WEB-INF/content路径下找物理视图资源,一旦我们使用@ResultPath(“/WEB-INF/jsps”)修饰该Action,系统将回到/WEB-INF/jsps目录下寻找物理视图资源。
[html] view plaincopy
  1. @ResultPath("/WEB-INF/jsps")  
  2. public class HelloWorld extends ActionSupport {  
  3.     public String execute() {  
  4.         return SUCCESS;  
  5.     }  
  6. }  
3、包和命名空间相关的Annotation:
       @Namespace:修饰Action类或其所在的包。该Annotation中指定一个value属性值,用于指定被修饰的Action所在的命名空间
       @Namespaces:修饰Action类或其所在的包,用于组合多个@Namespace
       @ParentPackage: 用于指定被修饰的Action所在包的父包。
4、 异常处理相关的Annotation
        4.1、@ExceptionMappings 用于组织多个@ExceptionMapping,因此它只需指定一个value属性值,该value属性值为多个@ExceptionMapping。
        4.2、@ExceptionMapping 用于定义异常类和物理视图之间的对应关系,也相当于struts.xml文件里<exception-mapping../>元素的作用 使用时,必须注意以下两个属性:
                  ①exception: 用于指定异常类
                  ②result : 用于指定逻辑视图
       4.3、@ExceptionMpping有如下两种用法
                  ①Action级的异常定义:以@ExceptionMappings组合多个@ExceptionMapping后修饰的Action类。这种异常定义对Action中的所有方法有效

[java] view plaincopy
  1. @ExceptionMappings({ @ExceptionMapping(exception = "java.lang.NullPointerException", result = "success", params = {  
  2.         "param1""val1" }) })  
  3. public class ExceptionsActionLevelAction {  
  4.   
  5.     public String execute() throws Exception {  
  6.         return null;  
  7.     }  
  8. }  
                ②方法级的异常定义: 将多个@ExceptionMapping组成数组后作为@Action的exceptionMappings属性值,这种异常定义仅对被修饰的方法有效。

[java] view plaincopy
  1. public class ExceptionsMethodLevelAction {  
  2.     @Action(value = "exception1", exceptionMappings = { @ExceptionMapping(exception = "java.lang.NullPointerException", result = "success", params = {  
  3.             "param1""val1" }) })  
  4.     public String run1() throws Exception {  
  5.         return null;  
  6.     }  
  7. }  

5、拦截器配置相关的Annotation
      5.1、与拦截器配置的Annotation有@InterceptorRef、@InterceptorRefs和@DefaultInterceptorRef
@InterceptorRefs用于组织多个@InterceptorRef,因此它只需要指定一个value属性值,该value属性值为多个@InterceptorRef

@InterceptorRef用于为指定Action引用lanjieq或者是拦截器栈。也就相当于strut.xml中位于<action../>元素内部的<interceptor-ref../>子元素的作用。使用@InterceptorRefAnnotation时,必须制定一个value属性,用于指定所引用的拦截器或拦截器栈的名字。相当于<interceptor-ref../>子元素里name属性的作用。

[java] view plaincopy
  1. @InterceptorRefs({ @InterceptorRef("interceptor-1"),@InterceptorRef("defaultStack") })  
  2. public class HelloWorld extends ActionSupport {  
  3.     @Action(value = "action1", interceptorRefs = @InterceptorRef("validation"))  
  4.     public String execute() {  
  5.         return SUCCESS;  
  6.     }  
  7.     @Action(value = "action2")  
  8.     public String doSomething() {  
  9.         return SUCCESS;  
  10.     }  
  11. }  

三、struts-plugin.xml 常量

默认常量:

[html] view plaincopy
  1. <constant name="struts.convention.actionConfigBuilder" value="convention"/>  
  2. <constant name="struts.convention.actionNameBuilder" value="convention"/>  
  3. <constant name="struts.convention.resultMapBuilder" value="convention"/>  
  4. <constant name="struts.convention.interceptorMapBuilder" value="convention"/>  
  5. <constant name="struts.convention.conventionsService" value="convention"/>  
  6. <constant name="struts.convention.result.path" value="/WEB-INF/content/"/>  
  7. <constant name="struts.convention.result.flatLayout" value="true"/>  
  8. <constant name="struts.convention.action.suffix" value="Action"/>  
  9. <constant name="struts.convention.action.disableScanning" value="false"/>  
  10. <constant name="struts.convention.action.mapAllMatches" value="false"/>  
  11. <constant name="struts.convention.action.checkImplementsAction" value="true"/>  
  12. <constant name="struts.convention.default.parent.package" value="convention-default"/>  
  13. <constant name="struts.convention.action.name.lowercase" value="true"/>  
  14. <constant name="struts.convention.action.name.separator" value="-"/>  
  15. <constant name="struts.convention.package.locators" value="action,actions,struts,struts2"/>  
  16. <constant name="struts.convention.package.locators.disable" value="false"/>  
  17. <constant name="struts.convention.package.locators.basePackage" value=""/>  
  18. <constant name="struts.convention.exclude.packages" value="org.apache.struts.*,org.apache.struts2.*,org.springframework.web.struts.*,org.springframework.web.struts2.*,org.hibernate.*"/>  
  19. <constant name="struts.convention.relative.result.types" value="dispatcher,velocity,freemarker"/>  
  20. <constant name="struts.convention.redirect.to.slash" value="true"/>  
  21. <constant name="struts.convention.action.alwaysMapExecute" value="true"/>  
  22. <constant name="struts.mapper.alwaysSelectFullNamespace" value="true"/>  
  23. <!-- <constant name="struts.convention.action.includeJars"  /> -->  
  24. <constant name="struts.convention.action.fileProtocols" value="jar" />  
  25. <constant name="struts.convention.classes.reload" value="false" />  
  26. <constant name="struts.convention.exclude.parentClassLoader" value="true" />  

Add a constant element to your struts config file to change the value of a configuration setting, like:

<constant name="struts.convention.result.path" value="/WEB-INF/mytemplates/"/>
NameDefault ValueDescriptionstruts.convention.action.alwaysMapExecutetrueSet to false, to prevent Convention from creating a default mapping to "execute" when there are other methods annotated as actions in the classstruts.convention.action.includeJars Comma separated list of regular expressions of jar URLs to be scanned. eg. ".myJar-0\.2.,.thirdparty-0\.1."struts.convention.action.packages An optional list of action packages that this should create configuration for (they don't need to match a locator pattern)struts.convention.result.path/WEB-INF/content/Directory where templates are locatedstruts.convention.result.flatLayouttrueIf set to false, the result can be put in its own directory: resultsRoot/namespace/actionName/result.extensionstruts.convention.action.suffixActionSuffix used to find actions based on class namesstruts.convention.action.disableScanningfalseScan packages for actionsstruts.convention.action.mapAllMatchesfalseCreate action mappings, even if no @Action is foundstruts.convention.action.checkImplementsActiontrueCheck if an action implements com.opensymphony.xwork2.Action to create an action mappingstruts.convention.default.parent.packageconvention-defaultDefault parent package for action mappinsstruts.convention.action.name.lowercasetrueConvert action name to lowercasestruts.convention.action.name.separator-Separator used to build the action name, MyAction -> my-action. This character is also used as the separator between the action name and the result in templates, like action-result.jspstruts.convention.package.locatorsaction,actions,struts,struts2Packages whose name end with one of these strings will be scanned for actionsstruts.convention.package.locators.disablefalseDisable the scanning of packages based on package locatorsstruts.convention.exclude.packagesorg.apache.struts.*,
org.apache.struts2.*,
org.springframework.web.struts.*,
org.springframework.web.struts2.*,
org.hibernate.*Packages excluded from the action scanningstruts.convention.package.locators.basePackage If set, only packages that start with its value will be scanned for actionsstruts.convention.relative.result.typesdispatcher,velocity,freemarkerThe list of result types that can have locations that are relative and the result location (which is the resultPath plus the namespace) prepended to themstruts.convention.redirect.to.slashtrueA boolean parameter that controls whether or not this will handle unknown actions in the same manner as Apache, Tomcat and other web servers. This handling will send back a redirect for URLs such as /foo to /foo/ if there doesn't exist an action that responds to /foostruts.convention.classLoader.excludeParenttrueExclude URLs found by the parent class loader from the list of URLs scanned to find actions (needs to be set to false for JBoss 5)struts.convention.action.eagerLoadingfalseIf set, found action classes will be instantiated by the ObjectFactory to accelerate future use, setting it up can clash with Spring managed beans

四、注意细节

1、当使用@Namespace将会覆盖类包定义的Namespace,其他定义的有效Namespace将不通过Action直接找该命名空间下的对应的视图。

2、当使用@Action(value = "/url")时,使用@Namespace定义的命名空间无效,该命名空间为content。

3、使用@Action(value = "url")时,同时使用了@Namespace,完整路径就是@Namespace+url

原创粉丝点击