用户在定义自己的拦截器类时,需要实现Interceptor接口。
拦截器执行顺序
每一个拦截器方法都有一个ActionInvocation类型的参数,在ActionInvocation接口中包含了一个invoke()方法,当在某一个拦截器中调用invoke()方法时,就会调用下一个拦截器方法,如此嵌套调用下去。如果当前拦截器是最后一个拦截器,则会调用Act ion的execute()方法。
:当一个请求到达Struts2框架时,Struts2框架首先找到能够处理该请求的Act ion,并找到与此Act
ion相关联的所有拦截器。Struts2框架创建一个ActionInvocation的实例,并调用其invoke()方法。invoke()方法的作用是判断是否还有下一个拦截器,如有,则调用下一个拦截器,否则直接跳到Act
ion的execute()方法去执行。
Demo
在Eclipse中创建一个Java Web项目
1、web.xml
ion包,在该包下创建FirstAction.java文件
ion包下创建SecondAction.java文件
SecondInterceptor
在上面的例子中,创建了3个相似的拦截器,这3个拦截器在Struts.xml文件中按顺序配置为一个拦截器栈,又配置了2个Act ion,第一个Act
ion的结果类型为chain,指向第二个Act
ion,因此在第一个Act
ion执行完后会执行第二个Act
ion,按照拦截器的执行顺序应该是第一个Act
ion先执行,然后调用第二个拦截器,再是第三个,然后是Act
ion调用,最后按相反的顺序执行拦截器为执行完的代码。
由于每个拦截器都会调用invocation.invoke()方法,这就会导致每个拦截器都会分为2个时段来执行自己的代码。
实际中更常用的一种方式是 继承抽象拦截器类AbstractInterceptor。AbstractInterceptor类实现了Interceptor接口,一般情况下只需实现intercept()方法。public interface Interceptor extends Serializable{ void init(); void destroy(); string intercept(ActionInvocation invocation)throws Exception; }
拦截器执行顺序
每一个拦截器方法都有一个ActionInvocation类型的参数,在ActionInvocation接口中包含了一个invoke()方法,当在某一个拦截器中调用invoke()方法时,就会调用下一个拦截器方法,如此嵌套调用下去。如果当前拦截器是最后一个拦截器,则会调用Act
:当一个请求到达Struts2框架时,Struts2框架首先找到能够处理该请求的Act
Demo
在Eclipse中创建一个Java Web项目
1、web.xml
2、在src目录下创建com.act<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!--定义欢迎页面--> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!--定义Filter--> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
3、在com.actpackage com.action; public class FirstAction { public String execute(){ System.out.println("First Action"); return "success"; } }
4、在src目录下创建包com.interceptor,在该包下创建FirstInterceptor.java文件package com.action; public class SecondAction { public String execute(){ System.out.println("second Action"); return "success"; } }
5、在com.interceptor包中创建SecondInterceptor.java 和 ThirdInterceptor.javapackage com.interceptor; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class FirstInterceptor extends AbstractInterceptor{ private static final long serialVersionUID = 1L; @Override public String intercept(ActionInvocation invocation ) throws Exception { System.out.println("第一个拦截器,在调用下一个拦截器或Action前"); String result = invocation.invoke(); //调用下一个拦截器 System.out.println("第一个拦截器,在代用下一个拦截器或Action后"); return result; } }
SecondInterceptor
ThirdInterceptorpackage com.interceptor; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class SecondInterceptor extends AbstractInterceptor{ private static final long serialVersionUID = 1L; @Override public String intercept(ActionInvocation invocation ) throws Exception { System.out.println("第二个拦截器,在调用下一个拦截器或Action前"); String result = invocation.invoke(); //调用下一个拦截器 System.out.println("第二个拦截器,在代用下一个拦截器或Action后"); return result; } }
6、在src目录下创建struts.xml文件package com.interceptor; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class ThirdInterceptor extends AbstractInterceptor{ private static final long serialVersionUID = 1L; @Override public String intercept(ActionInvocation invocation ) throws Exception { System.out.println("第三个拦截器,在调用下一个拦截器或Action前"); String result = invocation.invoke(); //调用下一个拦截器 System.out.println("第三个拦截器,在代用下一个拦截器或Action后"); return result; } }
7、在WebContent下创建success.jsp文件<?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> <constant name="struts.i18n.encoding" value="utf-8" /> <constant name="struts.multipart.saveDir" value="/tmp"/> <package name="struts2" extends="struts-default"> <!-- 配置拦截器 --> <interceptors> <interceptor name="firstInterceptor" class="com.interceptor.FirstInterceptor"/> <interceptor name="secondInterceptor" class="com.interceptor.SecondInterceptor"/> <interceptor name="thirdInterceptor" class="com.interceptor.ThirdInterceptor"/> <!-- 配置拦截器栈 --> <interceptor-stack name="mystack"> <interceptor-ref name="firstInterceptor"/> <interceptor-ref name="secondInterceptor"/> <interceptor-ref name="thirdInterceptor"/> <!--定义拦截器栈中的拦截器引用--> </interceptor-stack> </interceptors> <!-- 配置 Action --> <action name="firstaction" class="com.action.FirstAction"> <result type="chain">secondaction</result> <!-- 拦截器链 --> <interceptor-ref name="mystack"></interceptor-ref> </action> <action name="secondaction" class="com.action.SecondAction"> <result>success.jsp</result> </action> </package> </struts>
8、在WebContent下创建index.jsp文件<body> <center> <h2>success</h2> </center> </body>
9、运行结果<body> <center> <s:a action = "firstaction">invoke interceptor stack</s:a> </center> </body>
总结:
在上面的例子中,创建了3个相似的拦截器,这3个拦截器在Struts.xml文件中按顺序配置为一个拦截器栈,又配置了2个Act
由于每个拦截器都会调用invocation.invoke()方法,这就会导致每个拦截器都会分为2个时段来执行自己的代码。