Struts2--拦截器

     拦截器是Struts2的核心内容之一,号称完成了Struts框架的70%的工作,它体现了一种AOP(面向切面编程)的设计哲学,它还体现了软件开发领域DRY(Don’t repeat yourself)原则。


    Struts2中拦截器实际上也是一个类,它包含特殊的方法,能够拦截到要执行的方法,在这个方法执行之前或者之后插入其他功能,而且这些功能是自动完成的。个人理解,什么是拦截器呢,就像搞硬件的里面的中断器一样,拦截到正在执行的方法,强制在该方法前面插入一段代码,等待这段代码执行完毕,再执行拦截到的方法,然后还可以根据需要再次添加一段自动执行的方法。


    它的优势在于:提供更高层次的解耦。目标代码不需要手动调用目标方法,均是由系统自动完成。它在struts框架中发挥的作用包括:将params拦截HTTP请求的参数解析出来,设置成Action属性,Servlet-config拦截器将HTTP请求的HttpServletRequst和HttpServletResponse传给Action;fileUpload拦截器负责解析需要求情参数的文件域等等,这些拦截器都是系统默认配置完成的,位于struts-defults.xml文件下!

<interceptors>
            <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
            <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
            <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
            <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
            <interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/>
            <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" />
            <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" />
            <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
            <interceptor name="externalRef" class="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"/>
            <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
            <interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
            <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
            <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
            <interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
            <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
            <interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
            <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
            <interceptor name="actionMappingParams" class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/>
            <interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
            <interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
            <interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/>
            <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
            <interceptor name="sessionAutowiring" class="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"/>
            <interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
            <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>
            <interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
            <interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
            <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
            <interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
            <interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" />
            <interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />
            <interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" />
            <interceptor name="jsonValidation" class="org.apache.struts2.interceptor.validation.JSONValidationInterceptor" />
            <interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" />
            <interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor" />


【拦截器实现原理】


    我们先来用JDK动态代理(只能对实现了接口的实例动态生成代理)的方式来了解下拦截器的实现过程:


    1.创建实例接口:

       

	public interface Dog{
		Public void info();
		Public void run();
	}

    2.实例实现:

	Public class DogImpl implements dog
	{
		Public void info(){
			System.out.println("这是一只狗");
		}
		
		Poublic void run(){
			System.out.println("奔跑迅速");
		}
	}


    3. 创建拦截器类:

	Public class DogIntorcepter{
		Poublic void mathod1(){
			System.out.println("拦截器方法一");
		}
		
		Public void method2(){
			System.out.println("拦截器方法二");
		}
	}


    4. 创建代理句柄,实现系统 InvacationHandler,使其能够动态调用目标方法

	Public class ProxyHandler implements InvocationHandler{
		
		//需要被代理的目标对象
		Private Object target;
		
		//创建拦截器实例
		DogIntercepter di=new DogInterceptor();
		
		//执行目标对象方法时,invoke方法会自动调用
		Public Object invoe(object proxy,Method method,object[] args) throws Exception{
			Object result=null;
			
			If(method.getName().equals("info")){
			//如果调用了info方法,则先执行method1,然后执行info,最后执行method2
				Di.method1();
				Result=method.invoke(target,args);
				Di.method2();
			}else{
				Result=method.invoke(target,args);
			}
			
			Return result;
		}
		
		Public void setTarget(Object o){
			This.target=o;
		}
	
	}


    5. 代理工厂类,根据目标对象和对应的拦截器生成新代理对象(包含了目标方法和拦截器方法组合)
	Public class MyProxyFactory{
		Public static Object getProxy(Object object){
			
			//代理处理类
			ProxyHandler handler=new ProxyHandler();
			
			
			Handler.setTarget(object);
			
			//第一个参数是创建动态代理的classLoader对象(
			ClassLoader主要对类的请求提供服务,当JVM需要某类时,它根据名称向ClassLoader要求这个类,然后由ClassLoader返回这个类的class对象。
			)
			//第二个参数接口数组,代理该接口数组
			//第三个代理包含的处理实例
			
			Return Proxy.newProxyInstance(DogImpl.class.getClassLoader(),Object.getClass().getInterfaces(),handler);
			
		}
	}

    主程序:

	Public class TestDog{
		Poublic static void main(String[] args){
			Dog targetObject=new DogImpl();
			Dog dog=null;
			
			Object proxy=MyProxyFactory.getProxy(targetObject);
			If(proxy instance of Dog){
				Dog=(Dog)proxy;
			}
			
			//测试代理方法
			Dog.info();
			Dog.run();
			
		}
	}

     根据上面的过程,可以分析,拦截器和实例都是两个普通的类,通过实现InvacationHandler接口,将代理的方法有可能包含实例本身和拦截器的方法,并赋予一定的执行顺序,并通过JVM创建出动态代理对象,执行代理对象的info()方法,实际上执行了method1,info()和method2()方法。


【拦截器配置与使用】

      (1)自定义实现拦截器类,主要有两种方式,一是实现com.opensymphony.xwork2.interceptor.Interceptor接口,另一种则是继承AbstractInterceptor类,重写Interceptor方法

public class TheInterceptor1  implements Interceptor {

	private String test;
	
	public String getTest() {
		return test;
	}

	public void setTest(String test) {
		System.out.println("init setTest");
		this.test = test;
	}

	//拦截器被销毁之前,主要用于销毁init()申请的资源
	public void destroy() {
		// TODO Auto-generated method stub

	}

	//拦截器被初始化后,执行拦截之前,系统回调该方法,执行性一次,用于一些一次性资源,例如数据库连接
	public void init() {
		System.out.println("init invoked");
		
		System.out.println("test:"+this.test);

	}

	//用户需要的拦截动作
	public String intercept(ActionInvocation invocation) throws Exception {
		System.out.println("before");
		
		System.out.println("interceptor1:"+invocation.getAction().getClass());
		
		//在执行对应的Action方法之前,输出befor+拦截行为的类,之后输出after
		String resultString=invocation.invoke();
		
		System.out.println("after");
		return resultString;
	}

}

public class TheInterceptor2 extends AbstractInterceptor {

	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		System.out.println("interceptor vefore...");
		
		System.out.println("interceptor2:"+invocation.getAction().getClass());
		
		String resultString =invocation.invoke();
		
		System.out.println("interceptor after...");
		
		return resultString;
	}

}

    如果两个拦截器都被使用的话,则是一种嵌套存在的形式,例如,loginAction的execute同时配置了TheInterceptor1和 TheInterceptor2,则输出的结果为:

     before

     TheInterceptor1:loginAction

     before

     TheInterceptor2:loginAction

   LoginAction。execute的方法输出

   interceptor after...

   atter

 

   (2)在配置文件Struts.xml中的配置:

                      <interceptors>
				<interceptor name="theInterceptor1" class="org.whp.interceptor.TheInterceptor1">
					<param name="test">whp</param>
				</interceptor>
				
				<interceptor name="theInterceptor2" class="org.whp.interceptor.TheInterceptor2">
					
				</interceptor>
				<interceptor name="theInterceptor3" class="org.whp.interceptor.TheInterceptor3">
				
				</interceptor>
			</interceptors>


     为了能够达到拦截器复用的作用,还可以使用拦截器栈来配置:

<!-- 定义拦截器栈 -->
				<intercepetor-stack name="myDefaultInterceptorStack">
					<interceptor-ref name="loginInterceptor"></interceptor-ref>
					<interceptor-ref name="defaultInterceptor"></interceptor-ref>
				</intercepetor-stack>

 

     Action中配置对应的拦截器:

                 <action name="action1" class="org.whp.mystruts2.Action1">
				<result name="success" type="redirectAction">
					<param name="actionName">action2</param>
					<!-- <param name="username">${username}</param> -->
					<param name="username">${username1}</param>
					<param name="password">${password}</param>
					<param name="usernameAndPassword">${usernameAndPassword}</param>
				</result>
				
				<interceptor-ref name="theInterceptor1"></interceptor-ref>
				<interceptor-ref name="theInterceptor2"></interceptor-ref>
				<interceptor-ref name="theInterceptor3">
					<param name="includeMethods">execute,myExecute</param>  <!-- 对execute方法进行拦截 -->
					<!--<param name="excludeMethods">myExecute</param>  --> <!-- 不对myExecute进行拦截 -->
				</interceptor-ref>
				
				<interceptor-ref name="defaultStack"></interceptor-ref>
			</action>

    对各个action通用的拦截器,可以设置默认引用:

	<!-- 定义默认的拦截器,引用拦截器栈 -->
			<default-interceptor-ref name="myDefaultInterceptorStack"></default-interceptor-ref>


     


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值