Struts2拦截器

来源:互联网 发布:杭州网络维修招聘 编辑:程序博客网 时间:2024/06/05 06:05

为什么拦截请求

1.清理MVC

         把拦截器的所做的动作叫做横切,预处理,后加工。

       日志记录是一个典型的横切任务。日志记录是系统处理的每一个请求完成的关立兴任务。一般横切就是不是某一个动作特有,而是关联所有的动作。把日志记录转移到动作之外,从而创建更清晰的MVC关注点分离。

        数据转移是一个预处理。把不是特定动作核心的代码移除可以增加动作组件的纯度。

        拦截器可以改变工作流,例如验证拦截器,发现validate()方法有错误信息它就直接跳到input结果的页面。

2.从拦截器收益

       拦截器分层让软件更整洁,增加了可读性和可测试性,也提高了灵活性。从灵活性中得到两个益处就是可重用行和可配置。

拦截器的工作原理

1.ActionInvocation

        当框架接收到请求,先决定这个请求url映射到那个动作,这个动作的一个实例会被加入到新创建的ActionInvocation中,然后框架访问声明式架构,发现那些拦截器应该被触发。指向这些拦截器的引用会被加入到ActionInvocation中,其中还包括一些重要信息,例如servlet请求对象,当前动作可用的结果组件映射。

2.如何触发拦截器

        当ActionSupport创建了, 填充了需要的对象和信息。就可以调用了。ActionSupport调用invoke()方法访问第一个拦截器   ,在调用intercept()方法把控制权交给第一个拦截器。intercept()会把actionsupport实例当做一个参数来调用invoke()方法。就这样一直的递归调用,知道没有拦截器为止。或者拦截器返回一个控制字符串为止。
       在预处理阶段,拦截器能准备、过滤、改变或者操作任何可以访问的数据。
        调用invoke()方法或者转移控制流时,如果拦截器决定请求处理不应该继续,它可以不调用ActionSupport实例的invoke()方法,而是直接返回一个控制字符串。它可以停止后续操作,决定返回到那个结果。
        invoke()方法返回控制字符串后,任何一个返回的拦截器可以改变任何可以访问的对象或数据作为后加工。
        

内建的拦截器

1.工具拦截器

      1.1 timer拦截器

             这个拦截器记录执行的时间,从进入这个拦截器开始计时,到返回结果到这个浏览器为止。把这个放到拦截器的最后一个位置就是记录的动作执行时间,放到第一个位置就是记录通过拦截器和动作所执行的时间。

      1.2 logger拦截器

            这个拦截器提供了简单的日资记录机制。记录了预处理时进入声明和后加工退出声明。

2.数据转移拦截器

      2.1 params拦截器

             它将请求参数转移到通用的ValueStack公开(public)的属性上,它不知道数据最后去了哪里,只是把数据转移到ValueStack上发现的第一个匹配属性上,动作总是在请求周期开始时被放到ValueStack。所以params参数可以把参数放到动作中的属性上。

      2.2 static-params拦截器

            跟上面一样的效果,只是这个是转移的是声明式架构中的参数,这个和上面那个拦截器那个在前那个先触发,参数名一样会覆盖。
<action name="">     <param name="">value</param><action name="">

      2.3 autowiring拦截器

            这个拦截器为spring使用资源提供了一个集成点。

      2.4 servlet-config拦截器

            将servlet对象注入到动作中的方法,这个拦截器将各种对象设置到动作必须实现的接口的公开方法中。
             
ServlerContxtAware接口ServletContextServlerRequestAware接口HttpServletRequest对象ServlerResponseAware接口HttpServletResponse对象ParameterAware==设置Map类型的请求参数RequestAware 设置Map类型的请求属性SessionAware   设置Map类型的会话属性ApplicationAware设置Map类型的应用领域属性PrincipalAware设置principal对象(安全相关)

        2.5 fileUpload拦截器

              fileUpload拦截器把文件和元数据从多重请求中转换为常规的请求常数,可以设置到动作上。

3.工作流拦截器

         3.1 workflow拦截器

               提供数据验证,action中要有validate方法,出错返回到input结果中。
               参数:alwaysInvokeValidate true/false,默认true表示validate方法要被调用。
               inputResultName 失败返回的结果,默认Action,input。
               excludeMethods   拦截器不执行的方法名。可以省略动作特定入口方法的验证检查。

         3.2 validation拦截器

               提供了声明式的方式验证参数。默认在workflow拦截器前面。

         3.3 prepare拦截器

               看动作实现了Preparable接口,没有,接口定义了prepare()方法,这个拦截器会调用这个方法。如果不是execute方法,而是input(),则预处理方法为prepareInput()方法。不管哪个动作方法被调用,prepare总是执行。prepare方法在特定的方法后执行。

         3.4 modelDriven拦截器

                通过调用getModel()返回放在ValueStack上的模型对象。

4.其他拦截器

        4.1 exception拦截器

               一般放在拦截器的第一位,这样就可以捕获所产生的所有异常。然后返回到错误页面处理。

        4.2 token和token-session拦截器     

              防止表单重复提交。

        4.3 scoped-modelDriven

              为模型对象提供了跨域请求的向导式的持久性。

         4.4 execAndWait

               一个请求长时间执行时,可以有反馈。
内建的拦截器栈defaultStack

声明拦截器

      只能用xml声明式。不能用注解。

1.声明独立的拦截器和拦截器栈

      只能在package中声明
<package name="">    <interceptotrs>//声明拦截器          <interceptor name="" class=""/>           <interceptor name="" class=""/>     </interceptors>     <interceptor-stack name="">//拦截器栈            <interceptor-ref name="上面定义的name"/>             <interceptor-ref name="上面定义的name"/>              <interceptor-ref name="workflow">                    <param name="excludeMethods">input,back,cancel,browse</param>               </interceptor-ref>     </interceptor-stack>     <default-interceptor-ref name=""/>//默认用的拦截器栈</package>


从上面可以看到 struts中可以有package,include,bean,constant后面*号表示0个或多个。而且没有顺序。在package中只有action是可以有多个,其他的只能有0或一个。而且必须要按照上面的顺序。action在最后。

将拦截器映射到动作中

       动作属于继承了struts-default的包,但是要用拦截器就可以在动作中调用。
<action name="">   <interceptor-ref name="timer"/>   <interceptor-ref name="logger"/><interceptor-ref name="defaultStack"/>   <result ></result></action>

<interceptor-ref name="defaultstack"> <param name="workflow.excludeMethods"></param>可以覆盖workflow属性值</interceptor>
<interceptor-ref name="workflow"> <param name="excludeMethods"></param>可以改变workflow属性值</interceptor>

自定义拦截器

实现Interceptor接口有三个方法,void init(),void destroy(),String intercept(ActionInvocation aaa)throws Exception。在interceptor中要调用aaa.invoke()这个方法指定跳到下一个拦截器。
有参数的拦截器实现MethodFilterInterceptor接口。
让后在package中配置拦截器就行了。


0 0