struts-convention-plugin

struts-convention-plugin作用约定大于配置

减少了开发时间,但维护的时间并不会少;

注:使用struts2.3.24

struts需要导入的JAR就不多说了

Convention插件需要加入

asm.jar

asm.commons.jar

struts-convention-plugin.jar

  

<!-- 设置在class被修改时是否热加载,发布时要设置为false -->
  <constant name="struts.convention.classes.reload" value="true"/>
  <!-- 用于配置包名后缀。默认为action、actions、struts;value="action"为搜索action文件夹下的所有类-->
  <constant name="struts.convention.package.locators" value="action" />
  <!-- 用于配置类名后缀,默认为Action,设置后,Struts2只会去找这种后缀名的类做映射 -->
  <constant name="struts.convention.action.suffix" value="Action"/>
  <!-- 指定jsp文件所在的目录地址,默认为value="/WEB-INF/conent/"-->
<constant name="struts.convention.result.path" value="/WEB-INF/page/" />
<!-- 自定义jsp文件命名的分隔符 -->
<constant name="struts.convention.action.name.separator" value="-" />
<!-- 设置即使没有@Action注释,依然创建Action映射。默认值是false。因为Convention-Plugin是约定优于配置的风格, 可以不通过注解根据预先的定义就能访问相应Action中的方法 -->
<!-- <constant name="struts.convention.action.mapAllMatches" value="true"/> -->
<!--以下几个配置项就没测试过了--> <!-- 该常量指定包作为根包来搜索Action类。 Convention插件除了扫描默认的action,actions,struts,struts2, 还会扫描该常量指定的一个或多个包, Convention会试图从指定包中发现Action类。 -->
<!-- <constant name="struts.convention.action.packages" value="com.ackon.xxx" /> -->
<!-- 设置即使没有@Action注释,依然创建Action映射。默认值是false。因为Convention-Plugin是约定优于配置的风格, 可以不通过注解根据预先的定义就能访问相应Action中的方法 -->
<!-- <constant name="struts.convention.action.mapAllMatches" value="true"/> -->
<!-- 设置Convention插件是否从jar包中搜索Action类 [可选] 默认值为true -->
<constant name="struts.convention.action.disableJarScanning" value="true" />
<!-- 设置Convention插件文件协议类型 --><constant name="struts.convention.action.fileProtocols" value="jar,wsjar" />
<!-- 设置Convention插件需要搜索的jar包 -->
<constant name="struts.convention.action.includeJars" value=".*?/ackonOA*.*?jar(!/)?" />

 

com.ackon.oa.test.action.aa.TestaAction.java

访问方法: ip:prot/projectName/aa/testa!method1.do访问

例如此method1  return的string为”ta",则跳转的页面为/WEB-INF/page/aa/testa-ta.jsp

<constant name="struts.action.extension" value="do" /> struts访问action的扩展名

<constant name="struts.convention.result.path" value="/WEB-INF/page/" />决定页面目录

<constant name="struts.convention.action.suffix" value="Action"/>决定对应扫描注入的类为xxxAction.java

<constant name="struts.convention.package.locators" value="action" />和action.suffix决定了xxxAction.java的namespace,TestaAction.java的namespace为aa访问的模板页面在/WEB-INF/page/aa/下,具体页面testa-ta.jsp;

如com.ackon.oa.test.action,com.ackon.oa.action下的所有类都会被注入;com.ackon.oa.test.action下的目录aa下xxxAction的命名空间为aa

<constant name="struts.convention.action.name.separator" value="-" />设置页面间隔符,前一部分为actionName,  separator后的部分为具体页面。

http://localhost/ackonOA/aa/test-one.do访问com.ackon.oa.test.action.aa.TestOneAction的execute方法return SUCCESS,跳转至/WEB-INF/page/aa/test-one.jsp;t6() return "td";跳转至/WEB-INF/page/aa/test-one-td.jsp;

曾separator设置value="_",testa_ta.jsp和testa-ta.jsp同时存在时会去访问testa-ta.jsp,同一目录下只有testa_ta.jsp一个文件时才会去访问它;所以为了避免麻烦value="-"还是好一些;

<constant name="struts.convention.action.mapAllMatches" value="true"/>不起作用,设置为false,不用注解的方式仍可正常访问。

参照自己项目中的具体配置进行文件定位,所以在项目建立初期就最好引入struts-convention-plugin;

补充:引入struts-convention-plugin插件之前在struts.xml中进行配置的action访问方法仍可正常访问;

 

package com.ackon.oa.test.action;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;

import com.opensymphony.xwork2.ActionSupport;

public class TestaAction extends ActionSupport{
	public String execute(){
		System.out.println("---> TestaAction.execute(). SUCCESS");
		return SUCCESS;
	}

	@Action("a")
	public String t1(){
		System.out.println("---> TestaAction.t1(). SUCCESS");
		return SUCCESS;
	}
	
	@Action("/aa/a")
	public String t2(){
		System.out.println("--> TestaAction.t2(). ERROR");
		return ERROR;
	}
	
	@Action("aa/b")
	public String t3(){
		System.out.println("--> TestaAction.t3(). INPUT");
		return INPUT;
	}
	
	@Actions({
		@Action("b"),
		@Action("aa/test-one-td")
	})
	public String t4(){
		System.out.println("--> TestaAction.t4(). LOGIN");
		return LOGIN;
	}
	
	@Action("testa-ta")
	public String t5(){
		System.out.println("--> TestaAction.t5(). NONE");
		return NONE;
	}
	
	public String t6(){
		System.out.println("---> TestaAction.t6()");
		return "ta";
	}
	
     @Action("test-tb") public String t7(){ System.out.println("---> TestaAction.t7()"); return "tb"; } }

 注释掉@Action,即未加@Action注释前

localhost/ackonOA/testa.do 访问 execute() , 跳转至/WEB-INF/page/testa.jsp

localhost/ackonOA/testa!t1.do的形式访问自定义的方法,此为访问t1()

returnString为ACTION的五个常量时,SUCCESS,ERROR,INPUT,LOGIN跳转至/WEB-INF/page/testa.jsp; NONE跳转至空白页面;

t6()跳转至/WEB-INF/page/testa-ta.jsp

t7()跳转至/WEB-INF/page/testa-tb.jsp

 

 @Action注解改变Convention plug约定的action与url之间的映射关系

相当于多了一种调用方法的方式,只是会根据条用方式的不同,返回不同的结果页面

http://localhost/ackonOA/testa!t1.do访问t1()跳转至/WEB-INF/page/testa.jsp

http://localhost/ackonOA/a.do访问t1()跳转至/WEB-INF/page/a.jsp

 

http://localhost/ackonOA/aa/a.do跳转至/WEB-INF/page/aa/a.jsp

http://localhost/ackonOA/aa/b.do跳转至/WEB-INF/page/aa/b.jsp

此处注意@Action("/aa/a")和@Action("aa/b")在@Namespace中就有区别了,前面有"/"的为全限定名,@Namespace无法正确访问,此种方式不要用;

http://localhost/ackonOA/testa-ta.do访问t5(),因为返回NONE,跳转至空白页面,不响应;

http://localhost/ackonOA/test-tb.do访问t7(),跳转至/WEB-INF/page/test-tb.jsp

 @Namespace命名空间注释允许操作类名称空间改变而不是使用Convention Plugin约定的Java包的名称

package com.ackon.oa.test.action;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionSupport;

@Namespace("/aa")
public class TestbAction extends ActionSupport{
	public String execute(){
		System.out.println("---> TesteAction.execute()");
		return SUCCESS;
	}
	
	@Action("/testc")
	public String t1(){
		System.out.println("---> TesteAction.t1()");
		return "ta";
	}
	
	@Action("c")
	public String tb(){
		System.out.println("---> TesteAction.t2()");
		return "ta";
	}
}

正确格式@Namespace("/aa"),@Namespace("aa")是错误的,否则会造成访问页面与实际不符;

http://localhost/ackonOA/aa/testb.do访问execute,跳转至/WEB-INF/page/aa/testb.jsp

http://localhost/ackonOA/aa/testc.do访问t1(),无对应返回页面,可实际/WEB-INF/page/aa/testc.jsp存在

http://localhost/ackonOA/aa/c.do访问t2(),返回/WEB-INF/page/aa/c.jsp

t1()不能正常返回页面因为@Action("/testb")对action的命名空间进行了完全限定,而@Namespace注释的效果只能对该类未完全限定的Action URLs起作用,改为@Action("testb")即可

 @Results和@Result改变Conventiono plugin这种约定

package com.ackon.oa.test.action;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import com.opensymphony.xwork2.ActionSupport;

@Namespace("/b")
@Results({ @Result(name = "ta", location = "testa.jsp")})  
public class TestcAction extends ActionSupport {
	public String execute(){
		System.out.println("---> TestcAction.execute()");
		return "tc";
	}
	
	public String t0(){
		System.out.println("---> TestcAction.t0()");
		return "tb";
	}
	
	@Action("d")
	public String t1(){
		System.out.println("---> TestcAction.t1()");
		return "tb";
	}
	
	@Action("teste")
	public String t2(){
		System.out.println("---> TestcAction.t2()");
		return "ta";
	}
	
	@Actions({
		@Action("a"),
		@Action("b")
	})
	public String t3(){
		System.out.println("---> TestcAction.t3()");
		return "ta";
	}
	
	@Action(value = "c", results = {@Result(name = SUCCESS, location = "/WEB-INF/page/a.jsp")})
	public String t4(){
		System.out.println("---> TestcAction.t4()");
		return SUCCESS;
	}
	
	@Action(value = "/e", results = {@Result(name = "ta", location = "/WEB-INF/page/a.jsp")})
	public String t5(){
		System.out.println("---> TestcAction.t5()");
		return "ta";
	}
}

http://localhost/ackonOA/b/teste.do访问t2(),本应该返回/WEB-INF/page/b/teste.jsp,实际却返回/WEB-INF/page/b/testa.jsp

因为类定义了@Results({ @Result(name = "ta", location = "testa.jsp")})  

http://localhost/ackonOA/b/d.do和http://localhost/ackonOA/b/b.do都是访问t3()返回/WEB-INF/page/b/testa.jsp

t4()指定了@Action(value = "c", results = {@Result(name = SUCCESS, location = "/WEB-INF/page/a.jsp")})

returnString为SUCCESS返回location页面

http://localhost/ackonOA/b/c.do返回/WEB-INF/page/a.jsp

http://localhost/ackonOA/b/e.do访问t5();类和方法的返回值,方法的优先级高于类的,相当于覆盖了;

返回/WEB-INF/page/a.jsp,而不是/WEB-INF/page/b/testa.jsp

 

@Action(value = "c", results = {@Result(name = SUCCESS, location = "/WEB-INF/page/a.jsp")})可添加多个@Result

 

 Caused by: The action class [class com.ackon.oa.test.action.TestaAction] contains two methods with an action name annotation whose value is the same (they both might be empty as well). - [unknown location]

启动时报错,类中的两个方法调用方式相同,出现混乱;

 

posted @ 2016-01-31 15:43  陈&三  阅读(405)  评论(0编辑  收藏  举报