拦截器是动态拦截Action调用的对象,它定义一个action执行前后执行的代码,可以提取action中可重用部分的方式。拦截器可以在不修改源码的基础上,对动作方法进行增强。
拦截器VS过滤器
拦截器:是Struts2框架的,只有使用了Struts2框架才可以使用它;进入Struts2核心内部才起作用;多次调用。
过滤器:是Servlet规范的一部分,任何javaweb工厂都可以使用它;对所有要访问字段都拦截,容器初始化调用一次
拦截器执行机制
在访问Struts2核心内部时,在动作方法执行前正序执行,执行完动作方法和结果视图后,再倒序执行。
Strut.xml文件配置
在包里声明拦截器,同时在Action标签中引用拦截器
<struts>
<!-- 开启开发者模式 -->
<constant name="struts.devMode" value="true"></constant>
<package name="p" extends="struts-default">
<!-- 声明拦截器 -->
<interceptors>
<interceptor name="MyInterceptor1" class="com.itheima.interceptors.MyInterceptor1"></interceptor>
<interceptor name="MyInterceptor2" class="com.itheima.interceptors.MyInterceptor2"></interceptor>
</interceptors>
<action name="demo1" class="com.itheima.web.action.Demo1Action" method="demo1">
<!-- 引用拦截器1 2 -->
<interceptor-ref name="MyInterceptor1"></interceptor-ref>
<interceptor-ref name="MyInterceptor2"></interceptor-ref>
<!-- 视图回显 -->
<result name="success">/success.jsp</result>
</action>
</package>
</struts>
动作方法
public class Demo1Action extends ActionSupport {
public String demo1(){
System.out.println("Demo1Action类中的demo1方法执行了");
return SUCCESS;
}
}
拦截器1:
public class MyInterceptor1 extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("拦截器1:执行动作方法之前");
//进入拦截器2中
String str=invocation.invoke();
//打印拦截器中String内容
System.out.println(str);
System.out.println("拦截器1:执行动作方法之后");
return str;
}
}
拦截器2:
public class MyInterceptor2 extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("拦截器2:执行动作方法之前");
//进入动作方法Demo1Action的demo1()方法中
String str=invocation.invoke();
//打印拦截器中String内容
System.out.println(str);
System.out.println("拦截器2:执行动作方法之后");
return str;
}
}
success.jsp页面:
<%System.out.println("success.jsp执行了"); %>
当访问demo1.action时控制台显示: 执行图为:
注意:当我们是使用自己定义的拦截器的时候,struts2给我们提供的拦截器就失效了,所以需要将默认拦截器添加
<!-- 引入默认拦截器 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
设置默认拦截器:
<!-- 声明拦截器 -->
<interceptors>
<interceptor name="MyInterceptor1" class="com.itheima.interceptors.MyInterceptor1"></interceptor>
<interceptor name="MyInterceptor2" class="com.itheima.interceptors.MyInterceptor2"></interceptor>
<!-- 将新定义的拦截器和默认的拦截器组合成新的拦截器 -->
<interceptor-stack name="myDefaultStack">
<interceptor-ref name="MyInterceptor1"/>
<interceptor-ref name="MyInterceptor2"/>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 设置为默认拦截器 -->
<default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>
参数传递:
<param name="excludeMethods">login</param>
<param name="includeMethods">add,del</param>
解释:excludeMethods拦截器拦截的方法,includeMethods拦截器方式的方法
拦截器很大一部分是用在登录页面上,就像有时候我们在再未登录状态下访问网站内部信息,这个时候就会跳出登录页面让我们进行的登录操作。感觉越学到后面,很多内容都是和配置文件、反射有关的知识,所以我们需要把这些框架的内部逻辑搞清楚。