深入Struts2拦截器

 

         拦截器是 Struts2的一个重要的组成部分,可以说拦截器是一个勤劳的幕后工作者, Struts2的大部分功能都有拦截器完成了,也是由于拦截器的使用,使 Struts2成为一个非常 Clean的框架。你甚至不要在自己的 Action中写任何代码,一些重要的功能框架已帮你实现,如将请求参数到 Action中属性的传递,系统 Local的设置,参数验证等。 Strus2提供了大量的拦截器的实现,这些拦截器可以满足绝大不部分需求,我们完全可以复用框架提供的拦截器,而我们仅仅需要做的工作就是简单的几行配置,即可将系统提供的拦截器或自己开发的拦截器应用到自己的系统。而 Struts2拦截器的设计使我们很容易使用拦截器,但只有了解拦截器的工作原理,才能真正了解 Struts2框架。

        工作原理: Struts2的拦截器的实现原理和过滤器的实现差不多,对你真正想执行的 execute()方法进行拦截,然后插入一些自己的逻辑。如果没有拦截器,这些要插入的逻辑就得写在你自己的 Action实现中,而且每个 Action实现都要写这些功能逻辑,这样的实现非常繁琐。而 Struts2的设计者们把这些共有的逻辑独立出来,实现成一个个拦截器,既体现了软件复用的思想,又方便程序员使用。 Struts2中提供了大量的拦截器,多个拦截器可以组成一个拦截器栈,系统为我们配置了一个默认的拦截器栈 defaultStack,具体包括那些拦截器以及他们的顺序可以在 Struts2的开发包的 struts-default.xml中找到。在每次对你的 Action execute()方法请求时,系统会生成一个 ActionInvocation对象,这个对象保存了 action和你所配置的所有的拦截器以及一些状态信息。比如你的应用使用的是 defaultStack,系统将会以拦截器栈配置的顺序将每个拦截器包装成一个个 InterceptorMapping(包含拦截器名字和对应的拦截器对象 )组成一个 Iterator保存在 ActionInvocation中。在执行 ActionInvocation invoke()方法时会对这个 Iterator进行迭代,每次取出一个 InterceptorMapping,然后执行对应 Interceptor intercept(ActionInVocation inv)方法,而 intercept(ActionInInvocation inv)方法又包含当前的 ActionInInvcation对象作为参数,而在每个拦截器中又会调用 inv invoke()方法,这样就会进入下一个拦截器执行了,这样直到最后一个拦截器执行完,然后执行 Action execute()方法 (假设你没有配置访问方法,默认执行 Action execute()方法 )。在执行完 execute()方法取得了 result后又以相反的顺序走出拦截器栈,这时可以做些清理工作。最后系统得到了一个 result,然后根据 result的类型做进一步操作。

        ActionInvocation:这是个非常重要的类 ,它是 Struts2拦截器的核心,它保存了整个拦截器栈信息。了解了 ActionInvocation的功能就等于了解了 Struts2是怎样处理请求的,所以了解它对我们了解 Struts2的执行原理非常重要。当一个请求到来,框架会根据 URL从配置文件中得到对应的 Action类,然后新建一个 Action的实例保存在 ActionInvocation中,然后会根据配置得到你的拦截器栈,然后将这些拦截器信息以你配置的顺序添加到 ActionInvocation中, ActionInvocation还包含一些其他信息,如 result配置等。现在 ActionInvocaton已经包含了所有的配置信息,然后就是怎样执行这些拦截器和 Action类了 ,所有的这些步骤从 ActionInvocation invoke()方法开始。 Invoke()方法总是取出下一个拦截器来执行。而在拦截器中又会执行 ActionInvocation invoke()方法,这样就会按拦截器配置的顺序执行完所有的拦截器,最后执行 Action对应的方法。

          实现自己的拦截器:其实实现自己的拦截器是一个相当容易的事情,我们可以随便打开框架提供的默认实现拦截器的源码看看。比如最简单的 LoggingInterceptor,可以得到开发一个拦截器所需要的步骤和所需要注意的问题。首先,我们可以继承 AbstractInterceptor类,然后重写父类的 Intercept(ActionInvocation invocation)方法,我们可以看到 intercept(ActionInvocation invocation)方法签名中抛出异常,但我们无需在实现中捕获任何异常,因为框架为我们提供了 ExceptionMappingInterceptor来处理这些异常。只要注意一定要在 intercept()方法中要调用 invocation.invoke()方法 。注意:执行 invocation.invoke()逻辑之前执行的代码会在进入拦截器栈时执行,而执行 invocation.invoke()逻辑之后的代码会在离开拦截器栈的时候执行。这样,一个拦截器就开发完了,剩下的就是将自己开发的拦截器配置到自己的应用了。

Public class MyInterceptor extends AbstractInterceptor{

           Public String intercept(ActionInvocation invocation) throws Exception{

                     DoSomeThingBeforeGoIntoNextIntercept()

                     String result = invocation.invoke();

                      DoSomeCleanThing();

           }

 

}

配置拦截器:我们可以参考 struts-default.xml中拦截器的配置,一个拦截器栈可以包括一系列拦截器,在 Strus2中对拦截器配置用 <interceptors>节点,而 <interceptors>又可以包含 <interceptor> <interceptor-stack>。在 struts-2.1.dtd中对拦截器的配置定义: <!ELEMENT interceptors (interceptor|interceptor-stack)+>,按照配置定义,我们很容易就可以配置好自己的拦截器,在 <action>节点中我们可以用 <interception-ref/>节点来应用我们配置的拦截器,但是注意:在 struts-default.xml中,框架为我们配置了默认的拦截器栈 <default-interceptor-ref name=”defaultStack”>,如果我们在 <action>节点中配置了拦截器,则默认的拦截器则不会起作用,如果该 Action需要使用该默认拦截器,则必须将该默认拦截器配上。我们还可以在 Struts.xml中配置 <default-interceptor-ref>,它会覆盖 struts-default.xml中的配置,并在整个 <package>中起作用。

 

你可能感兴趣的:(xml,工作,框架,struts)