拦截器:拦截器类似于过滤器的功能,过滤器可以过滤项目的任何请求(servlet/jsp/html/img),拦截器只能拦截Action请求。
定义拦截器interceptor :实现Interceptor接口 实现必须的三个方法
init() :拦截器初始化 服务器启动时候就初始化所有需要的拦截器
intercept(ActionInvocation invocation):拦截 action访问的时候执行
destroy():销毁 服务器停止的时候销毁
申明和使用拦截器:
<package name="inter" extends="struts-default" namespace="/inter">
<!-- 申明拦截器:拦截器在此申明后,在web服务器启动的时候就会被初始化 -->
<interceptors>
<interceptor name="inter1" class="com.example.MyInterceptor1"></interceptor>
</interceptors>
<action name="user_*" class="com.example.UserAction" method="{1}">
<!-- 申明该action使用该拦截器:使用后,访问该action的请求,会先经过拦截器 -->
<interceptor-ref name="inter1"></interceptor-ref>
<result>/index.jsp</result>
</action>
</package>
拦截器生命周期:
1.启动服务器时候,申明在配置文件的拦截器,被初始化,调用init方法
2.当有请求访问拦截器作用的action时,先创建action对象,
3.执行该拦截器的intercepot方法拦截。在action目标方法 invocation.invoke()执行前后,写相应的业务逻辑。
4.当服务器停止时,拦截器对象才被销毁
拦截器作用范围:
1.局部使用:在action内部使用,只作用于该action
<action name="user_*" class="com.example.UserAction" method="{1}">
<!-- 使用拦截器 -->
<interceptor-ref name="inter1"></interceptor-ref>
<result>/index.jsp</result>
</action>
2.全局使用: 当package内,action外使用 作用于package内的所有action
<package name="inter" extends="struts-default" namespace="/inter">
<!-- 申明拦截器 -->
<interceptors>
<interceptor name="inter1" class="com.example.MyInterceptor1"></interceptor>
</interceptors>
<!-- 使用截器 -->
<default-interceptor-ref name="inter1"></default-interceptor-ref>
</package>
拦截器栈interceptor-stack:包含多个已经申明的拦截器。拦截器和拦截器栈都在interceptors标签内申明
定义拦截器栈的时候,引用拦截器的顺序决定了创建拦截器对象的顺序。(先指定就先创建)
<interceptors>
<interceptor name="inter1" class="com.example.MyInterceptor1"></interceptor>
<interceptor name="inter2" class="com.exampler.MyInterceptor2"></interceptor>
<!-- 定义栏截器栈 -->
<interceptor-stack name="interStack">
<interceptor-ref name="inter1"></interceptor-ref>
<interceptor-ref name="inter2"></interceptor-ref>
</interceptor-stack>
</interceptors>
拦截器栈中拦截器的执行顺序:
1.创建拦截器inter1对象,调用init方法
2.创建拦截器inter2对象,调用init方法
3.执行inter1的interceptor方法前面代码
4.执行inter2的interceptor方法前面代码
5.Action的业务方法
6.执行inter2的interceptor方法后面代码
7.执行inter1的interceptor方法前面代码
注意:当我们的包下引用了自定义拦截器栈,则会把默认包下的default-stack拦截器给覆盖掉
为了不覆盖默认拦截器,所以自定义的拦截器栈要加入Struts2默认的拦截器栈:
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"></interceptor-ref><!-- 引入了默认的18个拦截器 -->
<interceptor-ref name="interStack"></interceptor-ref><!-- 引入自定义的2个拦截器 -->
</interceptor-stack>
struts2的主要初始化流程:
1.创建StrutsPrepareAndExcuteFilter对象,执行init方法
2.加载default.properties配置文件
3.加载struts-default.xml struts-plug.xml struts.xml配置文件
4.初始化Struts默认配置的拦截器和自定义的拦截器,调用init方法
struts2的处理请求的主要流程:
如果请求目标是action ,Struts2框架拦截器才会处理,WebRoot下的静态资源是不会经过拦截器的。
1.依次执行对目标action起作用的拦截器的 intercept(ActionInvocation invocation)方法
2.调用actionInvocation .invocation()方法放行
3.创建目标action对象,调用目标方法,目标方法返回配置文件result需要的字符串标记,
4.根据目标方法返回的标记,跳到下一个action或者直接返回给浏览器result视图