1、structs2拦截器什么是Struts2拦截器? 从软件构架上来说,拦截器是实现了面向方面编程的组件。它将影响了多个业务对象的公共行为封装到一个个可重用的模块,减少了系统的重复代码,实现功能的高度内聚,确保了业务对象的整洁和纯度。 从Java代码上来说,它就是一个普度的Java对象,它只需要实现一个名为Interceptor的接口。为什么要使用拦截器? 拦截器消除了动作组件中的横切任务(cross-cutting task)。例如,日志记录是一个典型的横切关注。以前,我们可能需要为每个动作组件准备一些记录日志的代码。虽然这样看上去也没什么错误,但是一个不可以忽视的事实是这些用于记录日志的代码
2、并不是动作组件与模型交互的一部分。并且,日志记录是我们想为系统处理的每一个请求完成的管理性任务,它不是一个动作组件所特有的,而是贯穿了所有动作组件。Struts 2将这个功能放在了更高的层次上,我们可以能把日志记录的代码转移到动作组件之外,从而让动作组件更加简洁清晰。 拦截器组件提供了一个不错的场所,来将不同的横切关注点逻辑分成有层次的、可重用的部件。拦截器的工作原理? 当框架接收到一个请求的时候,它首先必须决定这个URL映射到哪一个动作组件。这个动作组件的一个实例就会被加入到一个新创建的ActionInvocation实例中。接着框架咨询声明性架构(XML配置文件或Java注解),以发现哪一
3、些拦截器应该被触发,以及按照什么样的顺序触发。将这些拦截器的引用添加到ActionInvocation中。除了这些核心元素,ActionInvocation也拥有其他重要的信息(Servlet请求对象和当前动作组件可用的结果组件列表)。 当ActionInvocation被创建完毕,并且填充了需要的所有对象和信息,就可以被使用了。ActionInvocation公开了一个invoke()方法,框架通过调用这个方法开始动作的执行。当框架调用了这个方法时,ActionInvocation通过执行拦截器栈中的第一个拦截器开始这个调用过程。需要注意的是,invoke()并不是总是指向拦截器栈的第一个拦
4、截器,ActionInvocation负责跟踪执行过程达到的状态,并且把控制交给栈中合适的拦截器(通过调用拦截器的intercept()方法将控制权交给拦截器)。通过递归调用(递归过程?框架通过第一次调用ActionInvocation对象的invoke()方法开始了这个过程。ActionInvocation通过调用拦截器的intercept()方法把控制权交给第一个拦截器。重要的是,intercept()方法把ActionInvocation实例作为一个参数。在拦截器的处理过程中,他会调用ActionInvocation实例参数的invoke()方法来继续调用后续拦截器的递归过程。因此,在通
5、常的执行中,调用过程向下通过所有拦截器,直到栈中再也没有拦截器时,触发动作。另外,ActionInvocation在内部管理处理状态,因此它总是直到自己现在处在栈的什么位置。)ActionInvocation的invoke()方法,拦截器栈中后续的拦截器继续执行,最终执行动作。这是因为每一次invoke()方法被调用时,ActionInvocation都会查询自身的状态,调用接下来的拦截器。在所有拦截器都被调用之后,invoke()方法会促使动作类执行。下面看一个简单的例子,演示上面所说的理论:TestActionpublic class TestAction extends ActionSu
6、pport private static final long serialVersionUID = 2753590609366162370L; Override public String execute() throws Exception System.out.println(execute); return SUCCESS; Interceptor1public class Intercept1 implements Interceptor private static final long serialVersionUID = 8596224826058233434L; public
7、 void destroy() public void init() public String intercept(ActionInvocation invocation) throws Exception System.out.println(interceptor1 begin); String result = invocation.invoke(); System.out.println(interceptor1 end); return result; Interceptor2public class Intercept2 implements Interceptor privat
8、e static final long serialVersionUID = -1580591331691823185L; public void destroy() public void init() public String intercept(ActionInvocation invocation) throws Exception System.out.println(interceptor2 begin); String result = invocation.invoke(); System.out.println(interceptor2 end); return resul
9、t; Interceptor3public class Intercept3 implements Interceptor private static final long serialVersionUID = 7081124564804422023L; public void destroy() public void init() public String intercept(ActionInvocation invocation) throws Exception System.out.println(interceptor3 begin); String result = invo
10、cation.invoke(); System.out.println(interceptor3 end); return result; 有三个自定以的拦截器,他们只是简单的输出几个字符串,拦截器开始将执行输出 interceptorx begin;拦截器结束时输出 interceptorx end; 将他们设置在一个指定的动作上 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 /index.jsp16 17 提交表单,控制台的输出结果:interceptor1 begininterceptor2 begininterceptor3 beginexecuteinter
11、ceptor3 endinterceptor2 endinterceptor1 end 从控制台输出的结果可以看出,在提交数据到框架时,框架调用拦截器的过程,首先框架会根据URL请求创建指定的动作TestAction,将TestAction的实例和TestAction相关的拦截器引用myStack放入一个新的ActionInvocation对象中(还包含其他信息),然后框架调用ActionInvocation的invoke()方法,此时开始了拦截器栈调用过程,最开始调用拦截器栈的第一个拦截器也就是Intercept1,拦截器执行完预处理后,因为intercept()方法接收一个ActionIn
12、vocation对象作为参数,在Intercept1.intercept()方法中继续调用 ActionInvocation对象的invoke()方法将向下继续调用栈中余下的拦截器Intercept2.一直到栈中没有拦截器为止,最后执行动作组件。在结果被呈现之后,拦截器会按照相反的顺序再触发一遍,使他们可以进行后处理。拦截器工作原理图:拦截器触发时能够做些什么?1. 做一些预处理。在这个阶段拦截器可以用来准备、过滤、改变或者操作任何可以访问的重要数据。这些数据包括所有与当前请求相关的关键对象和数据,也包括动作。2. 通过调用invoke()方法将控制转移给后续的拦截器,直到动作。或者通过返回一个控制字符串中断执行。在这个阶段,如果拦截器决定请求不应该继续,他可以不调用ActionInvocation实例上的invoke()方法,而是直接返回一个控制字符串。通过这种方式可以停止后续的执行,并且决定哪个结果被呈现。3. 做一些后加工。在这个阶段,任何一个返回的拦截器可以修改可以访问的对象的数据作为后加工,但是此时结果已经确定了。怎么声明拦截器?下面为Struts 2为我们提供的struts-default.xml文件部分: . dojo.*,struts.* input,back,cancel !- Sample
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1