`
yuanlanjun
  • 浏览: 1184184 次
文章分类
社区版块
存档分类
最新评论

struts2拦截器(一)

 
阅读更多
struts2拦截器


1、拦截器是基于java的反射机制的,而过滤器是基于函数回调
2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用
4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能
5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次


执行顺序:过滤前 – 拦截前 – Action处理 – 拦截后 – 过滤后



一.概念

--拦截器(Interceptor)是动态拦截Action调用的对象,类似于Servlet中的过滤器,在执行Action的业务逻辑处理方法(execute())之前,struts2会首先执行在struts.xml中引用的拦截器。
--拦截器是struts2的一个重要特性,Struts2框架的大多数核心功能都是通过拦截器来实现的,像避免避免表单重复提交,类型转换,对象组装,验证,文件上传等,都是在拦截器的帮助下实现的。拦截器可以在Action执行之前和执行之后拦截调用。


二.拦截器实现原理

--struts2拦截器的基本实现相当于方法的嵌套调用。
--Struts2的拦截器机制采用了使用动作调用链的方式来嵌套调用拦截器,并将动作调用链封装在实现ActionInvocation接口的类中,而且每一个拦截器方法都有一个ActionInvocation类型的参数,在ActionInvocation接口中有一个invoke方法,在某一个拦截器方法中调用invoke方法时,就会调用下一个拦截器方法,如果当前拦截器是最后一个拦截器,就会调用Action的execute方法。


三.模拟Struts2实现一个拦截器系统

MyInvocation:

package lanjieqi.struts2;

import java.util.LinkedList;
import java.util.List;




public class MyInvocation {
	private List<Interceptor> interceptors = new LinkedList<Interceptor>();// 保存拦截器对象
	private Object action;// 被拦截的对象
	private int interceptorIndex = 0;// 拦截器的调用索引

	// 构造方法,用于注册拦截器和Action 对象
public MyInvocation(Object action, Interceptor... interceptor) {
		// 将拦截器对象加到interceptors中
		for (int i = 0; i < interceptor.length; i++) {
			// 将拦截器添加到List集合
			this.interceptors.add(interceptor[i]);
		}
		this.action = action;
	}

	// 执行调用链中的拦截器方法和execute方法
	public void invoke() throws Exception {
		// 调用链中的所有拦截器方法都执行完了,开始调用execute方法
		if (interceptorIndex == interceptors.size()) {
			try {
				// 通过反射技术在Action 对象中寻找execute方法如果未找到,将跑出异常
				java.lang.reflect.Method method = action.getClass().getMethod(
						"execute");
				method.invoke(getAction());
			} catch (Exception e) {
				throw new Exception("在action中未发现execute方法");
			}
			return;
		}
		interceptors.get(interceptorIndex++).intercept(this);
	}

	// 获得Action对象
	public Object getAction() {
		return this.action;
	}

}
Interceptor接口:

package lanjieqi.struts2;

public interface Interceptor {
//拦截器方法
	public void intercept(MyInvocation invocation) throws Exception;
}

Property接口:

package lanjieqi.struts2;

public interface Property {
public String getValue();
}

MyAction:

package lanjieqi.struts2;



public class MyAction implements Property{

	@Override
	public String getValue() {
		// TODO Auto-generated method stub
		return "属性值";
	}
	public void execute(){
		System.out.println("execute");
	}
}

PropertyInterceptor:相当于ModelDriven拦截器的作用

package lanjieqi.struts2;

public class PropertyInterceptor implements Interceptor{

	@Override
	public void intercept(MyInvocation invocation) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("PropertyInterceptor before invoke");
		//获得MyAction对象实例
		Object action = invocation.getAction();
		//判断MyAction类是否实现了Property接口
		if(action instanceof Property){
			Property property = (Property)action;
			//将MyAction对象转化成Property对象
			//输出getValue方法返回值
			System.out.println("property value:"+property.getValue());
		}
		invocation.invoke();//调用invoke方法来执行调用链中下一个拦截器方法
		System.out.println("PropertyInterceptor after invoke");
	}

}

MyInterceptor1:

package lanjieqi.struts2;

public class MyInterceptor1 implements Interceptor {

	@Override
	public void intercept(MyInvocation invocation) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("MyInterceptor1 before invoke");
		invocation.invoke();
		System.out.println("MyInterceptor1 after invoke");
	}

}

MyInterceptor2:

package lanjieqi.struts2;

public class MyInterceptor2 implements Interceptor {

	@Override
	public void intercept(MyInvocation invocation) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("MyInterceptor2 before invoke");
		invocation.invoke();
		System.out.println("MyInterceptor2 after invoke");
	}

}

TestInterceptor:

package lanjieqi.struts2;

public class TestInterceptor {
	public static void main(String args[]) throws Exception {
		MyInterceptor1 myinterceptor1 = new MyInterceptor1();
		MyInterceptor2 myinterceptor2 = new MyInterceptor2();
		PropertyInterceptor propertyinterceptor = new PropertyInterceptor();
		MyAction action = new MyAction();
		MyInvocation myinvocation = new MyInvocation(action, myinterceptor1,
				myinterceptor2, propertyinterceptor);
		myinvocation.invoke();
	}
}

测试执行结果:



这个拦截器执行的全过程是:MyInterceptor1-MyInterceptor2-PropertyInterceptor-MyAction中的execute方法-PropertyInterceptor-MyInterceptor2-MyInterceptor1

PropertyInterceptor最先全部执行完成,其次是MyInterceptor2,最后是MyInterceptor1


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics