Struts2--拦截器

来源:互联网 发布:手机淘宝降价通知设置 编辑:程序博客网 时间:2024/05/18 00:48

     拦截器是Struts2的核心内容之一,号称完成了Struts框架的70%的工作,它体现了一种AOP(面向切面编程)的设计哲学,它还体现了软件开发领域DRY(Don’t repeat yourself)原则。


    Struts2中拦截器实际上也是一个类,它包含特殊的方法,能够拦截到要执行的方法,在这个方法执行之前或者之后插入其他功能,而且这些功能是自动完成的。个人理解,什么是拦截器呢,就像搞硬件的里面的中断器一样,拦截到正在执行的方法,强制在该方法前面插入一段代码,等待这段代码执行完毕,再执行拦截到的方法,然后还可以根据需要再次添加一段自动执行的方法。


    它的优势在于:提供更高层次的解耦。目标代码不需要手动调用目标方法,均是由系统自动完成。它在struts框架中发挥的作用包括:将params拦截HTTP请求的参数解析出来,设置成Action属性,Servlet-config拦截器将HTTP请求的HttpServletRequst和HttpServletResponse传给Action;fileUpload拦截器负责解析需要求情参数的文件域等等,这些拦截器都是系统默认配置完成的,位于struts-defults.xml文件下!

<interceptors>            <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>            <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>            <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>            <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>            <interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/>            <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" />            <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" />            <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />            <interceptor name="externalRef" class="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"/>            <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>            <interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>            <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>            <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>            <interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>            <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>            <interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>            <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>            <interceptor name="actionMappingParams" class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/>            <interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>            <interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>            <interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/>            <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>            <interceptor name="sessionAutowiring" class="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"/>            <interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>            <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>            <interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>            <interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>            <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>            <interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />            <interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" />            <interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />            <interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" />            <interceptor name="jsonValidation" class="org.apache.struts2.interceptor.validation.JSONValidationInterceptor" />            <interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" />            <interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor" />


【拦截器实现原理】


    我们先来用JDK动态代理(只能对实现了接口的实例动态生成代理)的方式来了解下拦截器的实现过程:


    1.创建实例接口:

       

public interface Dog{Public void info();Public void run();}

    2.实例实现:

Public class DogImpl implements dog{Public void info(){System.out.println("这是一只狗");}Poublic void run(){System.out.println("奔跑迅速");}}


    3. 创建拦截器类:

Public class DogIntorcepter{Poublic void mathod1(){System.out.println("拦截器方法一");}Public void method2(){System.out.println("拦截器方法二");}}


    4. 创建代理句柄,实现系统 InvacationHandler,使其能够动态调用目标方法

Public class ProxyHandler implements InvocationHandler{//需要被代理的目标对象Private Object target;//创建拦截器实例DogIntercepter di=new DogInterceptor();//执行目标对象方法时,invoke方法会自动调用Public Object invoe(object proxy,Method method,object[] args) throws Exception{Object result=null;If(method.getName().equals("info")){//如果调用了info方法,则先执行method1,然后执行info,最后执行method2Di.method1();Result=method.invoke(target,args);Di.method2();}else{Result=method.invoke(target,args);}Return result;}Public void setTarget(Object o){This.target=o;}}


    5. 代理工厂类,根据目标对象和对应的拦截器生成新代理对象(包含了目标方法和拦截器方法组合)
Public class MyProxyFactory{Public static Object getProxy(Object object){//代理处理类ProxyHandler handler=new ProxyHandler();Handler.setTarget(object);//第一个参数是创建动态代理的classLoader对象(ClassLoader主要对类的请求提供服务,当JVM需要某类时,它根据名称向ClassLoader要求这个类,然后由ClassLoader返回这个类的class对象。)//第二个参数接口数组,代理该接口数组//第三个代理包含的处理实例Return Proxy.newProxyInstance(DogImpl.class.getClassLoader(),Object.getClass().getInterfaces(),handler);}}

    主程序:

Public class TestDog{Poublic static void main(String[] args){Dog targetObject=new DogImpl();Dog dog=null;Object proxy=MyProxyFactory.getProxy(targetObject);If(proxy instance of Dog){Dog=(Dog)proxy;}//测试代理方法Dog.info();Dog.run();}}

     根据上面的过程,可以分析,拦截器和实例都是两个普通的类,通过实现InvacationHandler接口,将代理的方法有可能包含实例本身和拦截器的方法,并赋予一定的执行顺序,并通过JVM创建出动态代理对象,执行代理对象的info()方法,实际上执行了method1,info()和method2()方法。


【拦截器配置与使用】

      (1)自定义实现拦截器类,主要有两种方式,一是实现com.opensymphony.xwork2.interceptor.Interceptor接口,另一种则是继承AbstractInterceptor类,重写Interceptor方法

public class TheInterceptor1  implements Interceptor {private String test;public String getTest() {return test;}public void setTest(String test) {System.out.println("init setTest");this.test = test;}//拦截器被销毁之前,主要用于销毁init()申请的资源public void destroy() {// TODO Auto-generated method stub}//拦截器被初始化后,执行拦截之前,系统回调该方法,执行性一次,用于一些一次性资源,例如数据库连接public void init() {System.out.println("init invoked");System.out.println("test:"+this.test);}//用户需要的拦截动作public String intercept(ActionInvocation invocation) throws Exception {System.out.println("before");System.out.println("interceptor1:"+invocation.getAction().getClass());//在执行对应的Action方法之前,输出befor+拦截行为的类,之后输出afterString resultString=invocation.invoke();System.out.println("after");return resultString;}}

public class TheInterceptor2 extends AbstractInterceptor {@Overridepublic String intercept(ActionInvocation invocation) throws Exception {System.out.println("interceptor vefore...");System.out.println("interceptor2:"+invocation.getAction().getClass());String resultString =invocation.invoke();System.out.println("interceptor after...");return resultString;}}

    如果两个拦截器都被使用的话,则是一种嵌套存在的形式,例如,loginAction的execute同时配置了TheInterceptor1和TheInterceptor2,则输出的结果为:

     before

     TheInterceptor1:loginAction

     before

     TheInterceptor2:loginAction

   LoginAction。execute的方法输出

   interceptor after...

   atter

 

   (2)在配置文件Struts.xml中的配置:

                      <interceptors><interceptor name="theInterceptor1" class="org.whp.interceptor.TheInterceptor1"><param name="test">whp</param></interceptor><interceptor name="theInterceptor2" class="org.whp.interceptor.TheInterceptor2"></interceptor><interceptor name="theInterceptor3" class="org.whp.interceptor.TheInterceptor3"></interceptor></interceptors>


     为了能够达到拦截器复用的作用,还可以使用拦截器栈来配置:

<!-- 定义拦截器栈 --><intercepetor-stack name="myDefaultInterceptorStack"><interceptor-ref name="loginInterceptor"></interceptor-ref><interceptor-ref name="defaultInterceptor"></interceptor-ref></intercepetor-stack>

 

     Action中配置对应的拦截器:

                 <action name="action1" class="org.whp.mystruts2.Action1"><result name="success" type="redirectAction"><param name="actionName">action2</param><!-- <param name="username">${username}</param> --><param name="username">${username1}</param><param name="password">${password}</param><param name="usernameAndPassword">${usernameAndPassword}</param></result><interceptor-ref name="theInterceptor1"></interceptor-ref><interceptor-ref name="theInterceptor2"></interceptor-ref><interceptor-ref name="theInterceptor3"><param name="includeMethods">execute,myExecute</param>  <!-- 对execute方法进行拦截 --><!--<param name="excludeMethods">myExecute</param>  --> <!-- 不对myExecute进行拦截 --></interceptor-ref><interceptor-ref name="defaultStack"></interceptor-ref></action>

    对各个action通用的拦截器,可以设置默认引用:

<!-- 定义默认的拦截器,引用拦截器栈 --><default-interceptor-ref name="myDefaultInterceptorStack"></default-interceptor-ref>


     


0 0