作用
拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。
拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。
拦截器栈(Interceptor Stack)类似于过滤器链。拦截器栈就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器栈的拦截器就会按其之前定义的顺序被调用。
也可以叫做拦截器链(Interceptor Stack),拦截器栈一词更明确的表名了连接器链的实现方式。
Struts2的拦截器和Filter类似。在执行Action的execute方法之前,Struts2会首先执行在struts.xml中引用的拦截器,在执行完所有引用的拦截器的intercept方法后,会执行Action的execute方法。
当请求到达Struts 2的ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器。
使用
- 自定义一个普通类。
- 继承 AbstractInterceptor 类,使该类变为拦截器类
- 重写类中的 intercept 方法
- 在 intercept 方法中实现业务逻辑。
- 如果调用 invocation.invoke() 方法,则是需要放过被拦截的方法。
- return 的字符串,会在struts.xml文件中找对应的<result></result> 结果集,跳转到相对应的页面(比如登录页面等)。
- 在struts.xml文件中添加拦截器的配置。
- 配置自定义拦截器
- 配置自定义拦截器栈
- 配置默认使用的拦截器栈
示例
- 自定义的拦截器类
package com.mr.interceptor;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
/**
* 1:继承 AbstractInterceptor 类,使该类变为拦截器类
* 2:重写类中的 intercept 方法
* 3:在 intercept 方法中实现业务逻辑。
* 4:如果调用 invocation.invoke() 方法,则是需要放过被拦截的方法
* 5:return 的字符串,会在struts.xml文件中找对应的<result></result> 结果集,
* 跳转到相对应的页面(比如登录页面等)。
*/
public class MyInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("进入拦截器!");
// 获取到actionName
String name = ServletActionContext.getContext().getName();
if("loginAction".equals(name)) {
return invocation.invoke();// 返回 invocation.invoke() 代表放行该方法
}
return "toLogin"; //返回字符串,会在struts.xml文件中找对应的<result></result> 结果集
}
}
- struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!--
package提供了将多个Action组织为一个模块的方式 package的名字必须是唯一的
package可以扩展 当一个package扩展自 另一个package时
该package会在本身配置的基础上加入扩展的package 的配置
父package必须在子package前配置
name:package名称
extends:继承的父package名称
abstract:设置package的属性为抽象的 抽象的package不能定义action 值true:false
namespace:定义package命名空间 该命名空间影响到url的地址,
例如此命名空间为/test那么访问是的地址为http://localhost:8080/struts2/test/XX.action -->
<package name="struts2" extends="struts-default">
<!-- 拦截器 -->
<interceptors>
<!-- 自定义拦截器 -->
<interceptor name="myInterceptor" class="com.mr.interceptor.MyInterceptor"></interceptor>
<!-- 自定义拦截器栈 -->
<interceptor-stack name="myStack">
<!-- 引入自定义拦截器 -->
<interceptor-ref name="myInterceptor"/>
<!--
引入默认的拦截器栈
注意:这个拦截器栈是必须引入的,因为struts2的默认工作需要使用该拦截器栈。
-->
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<!-- 默认使用的拦截器栈:只要是该<package> 标签中的 <action> 全部会被引用到 -->
<default-interceptor-ref name="myStack"></default-interceptor-ref>
<!--
自定义全局的结果集
该package中的所有返回值,都可以找该结果集
-->
<global-results>
<result name="toLogin">/index.jsp</result>
</global-results>
<!--
Action配置
一个Action可以被多次映射(只要action配置中的name不同)
name:action名称 class:
对应的类的路径
-->
<action name="hello" class="com.mr.action.HelloAction">
<!--
节点配置
name : result名称 和Action中返回的值相同
type : result类型 不写则选用superpackage的type
struts-default.xml中的默认为dispatcher
dispatcher :转发
redirect :重定向
-->
<result name="hello">/WEB-INF/view/hello.jsp</result>
</action>
</package>
</struts>