一, 概述
二, 在 Struts2 中使用拦截器
2.1 步骤
2.2 分析拦截器原理
2.3 关于 interceptor 与 Filter 区别:
三, 案例
一, 概述
介绍拦截器:
struts2 拦截器使用的是 AOP(面向切面编程) 思想. AOP 的底层实现就是动态代理. 拦截器采用责任链模式 , 在责任链模式里, 很多对象由每一个对象对其下家的引用而连接起来形成一条链. 责任链每一个节点, 都可以继续调用下一个节点, 也可以阻止流程继续执行. struts2 中在 struts-default.xml 文件中声明了所有的拦截器. 而 struts2 框架默认使用的是 defaultStack 这个拦截器栈. 在这个拦截器栈中使用了 18 个拦截器. 简单说, struts2 框架在默认情况下, 加载了 18 个拦截器. 可以通过使用拦截器进行控制 action 的访问. 例如, 权限操作
二, 在 Struts2 中使用拦截器
2.1 步骤
1. 创建一个 Interceptor 可以自定义一个类实现 com.opensymphony.xwork2.interceptor.Interceptor
在这个接口中有三个方法 init destroy intercept, intercept 方法是真正拦截的方法.
在 intercept 方法中如果要向下继续执行, 通过其参数 ActionInvocation 调用它的 invoke() 方法就可以.
2. 声明一个 Interceptor
参考 struts-default.xml 文件中配置, 在 struts.xml 文件中要自己声明一个 interceptor
3. 在 action 中指定使用哪些拦截器.
注意: 只要显示声明使用了一个拦截器. 那么默认的拦截器就不在加载.
2.2 分析拦截器原理
源代码执行流程:
1. 在 StrutsPrepareAndExecuteFilter 中查找, 在 doFilter 方法内有一句话 execute.executeAction (request, response, mapping) 执行 Action 操作.
2. 在 executeAction 执行过程中会访问 Dispatcher 类中的 serviceAction, 在这个方法中会创建一个 ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, method, extraContext, true, false); 这就是我们的 Action 的代理对象
3. 查看 ActionInvocation, 查看其实现类 DefaultActionInvocation. 在其 invoke 方法中:
- if (interceptors.hasNext()) {// 判断是否有下一个拦截器.
- final InterceptorMapping interceptor = interceptors.next(); // 得到一个拦截器
- String interceptorMsg = "interceptor:" + interceptor.getName();
- UtilTimerStack.push(interceptorMsg);
- try {
- resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
- // 调用得到的拦截器的拦截方法. 将本类对象传递到了拦截器中.
- }
- finally {
- UtilTimerStack.pop(interceptorMsg);
- }
- }
通过源代码分析, 发现在 DefaultActionInvocation 中就是通过递归完成所有的拦截调用操作.
2.3 关于 interceptor 与 Filter 区别:
1, 拦截器是基于 java 反射机制的, 而过滤器是基于函数回调的.
2, 过滤器依赖于 servlet 容器, 而拦截器不依赖于 servlet 容器.
3, 拦截器只能对 Action 请求起作用, 而过滤器则可以对几乎所有请求起作用.
4, 拦截器可以访问 Action 上下文, 值栈里的对象, 而过滤器不能.
5, 在 Action 的生命周期中, 拦截器可以多次调用, 而过滤器只能在容器初始化时被调用一次.
三, 案例
权限控制:
1.login.jsp------>LoginAction------------->book.jsp, 登录成功, 将用户存储到 session.
2. 在 book.jsp 中提供 crud 链接. 每一个连接访问一个 BookAction 中一个方法.
要求: 对于 BookAction 中的 add,update,delete 方法要求用户必须登录后才可以访问. search 无要求.
要控制 action 中某些方法的拦截
1. 创建类不在实现 Interceptor 接口, 而是继承其下的一个子类. MethodFilterInterceptor, 不用在重写 intercept 方法, 而是重写 doIntercept 方法.
- public class BookInterceptor extends MethodFilterInterceptor {
- @Override
- protected String doIntercept(ActionInvocation invocation) throws Exception {
- // 1. 得到 session 中的 user
- User user = (User) ServletActionContext.getRequest().getSession()
- .getAttribute("user");
- if (user == null) {
- BookAction action = (BookAction) invocation.getAction(); // 得到当前拦截的 action 对象.
- action.addActionError("权限不足, 请先登录");// 存储错误信息
- return Action.LOGIN;
- }
- return invocation.invoke();
- }
- }
2. 在 struts.xml 文件中声明
- <interceptors>
- <intercept name=""class="">
- <param name="includeMethods">add,update,delete</param>
- <param name="excludeMethods">search</param>
- </intercept>
- </interceptors>
来源: http://www.bubuko.com/infodetail-3282382.html