[Struts2 in action 笔记3]坐享其成的拦截器(栈)

前言-

  学习Struts初期一直有个疑问,虽然早就听闻Struts-interceptor的大名,但却一直没有实际使用过他,甚至连配置文件里也不见踪影,动作Action则是随处可见。但是在框架后台工作的拦截器interceptor才是真正的英雄。在struts-default包中的默认拦截器栈defaultStack已经处理了大部分的基础任务,从数据转移到异常处理。也正是有了这一套丰富的内建拦截器,你可以坐享其成,使用defaultStack而非自己编写拦截器interceptor。但是学习理解并创建自己的拦截器仍是十分必要的。

  关于struts-default包,她在struts2-core-2.x.x  jar下,你可以使用解压软件解压并找到她,查看它的代码有助于理解defaultStack都包含什么拦截器,以及他们的顺序。

  关于使用struts-default包,平时在struts.xml中的编写package都会继承她(继承她才能在后面使用defalultStack。。。)

本文为个人《Struts2 in Action》的学习笔记,如有错误请及时通知我。

正文-

ActionInvocation:

每当一个Action被触发,框架不是简单的调用Action的execute()方法,而是创建一个名为ActionInvocation的对象,她包含着动作和一系列的拦截器,大概是这个样子的:

 

[Struts2 in action 笔记3]坐享其成的拦截器(栈)_第1张图片

 

 

ActionInvocation的工作工程:

 

当框架收到一个请求时,她首先必须决定这个URL指向了哪个动作Action。

这个Action的一个实例会被加入到一个新创建的ActionInvocation实例中。

接着ActionInvocation会询问配置文件,确定需要什么拦截器,以及以什么样的顺序触发他们。

随后这些拦截器也会被加入ActionInvocation中。

[Struts2 in action 笔记3]坐享其成的拦截器(栈)_第2张图片

 

 

struts内部拦截器:

工具拦截器:timer(时间拦截器),logger(简单日志记录)

数据转移拦截器:params(将参数转移到ValueStack上,defaultStack)

        static-params(将xml配置文件的设置参数转移到ValueStack,defaultStack)并在params之前

        fileUpload(将文件和元数据装换为常规请求参数,defaultStack)

        autowirting(Spring相关)

        servlet-config(将Servlet对象注入action的方法,defaultStack)

        • ServletContextAware设置ServletContext
        • ServletRequestAware设置ServletRequest
        • ServletResponseAware设置ServletResponse
        • ParameterAware设置Map类型请求参数
        • RequestAware设置Map类型的请求属性
        • SessionAware设置Map类型的会话属性
        • ApplicationAware设置Map类型的应用程序领域属性
        • PrincipalAware设置Principal对象(安全相关)

工具流拦截器:workflow(数据验证等,defaultStack)

       vaildation(数据验证,defaultStack)

       prepare(追加额外处理,defaultStack)

       modeldriven(老朋友了,将对象放在ValueStack请求参数,defaultStack)

其他拦截器:exception(defaultStack),token,token-session,scoped-modeldriven(defaultStack),execAndWait

 

自定义拦截器:

编写自定义拦截器时需要实现Interceptor接口,这里接口下只有三个方法

void destroy();
void init();
String intercept(ActionInvocation invocation)throws Exception;

前两个时典型的生命周期函数,真正的业务逻辑发生在intercept()中

AuthenticationInterceptor.java
public
String intercept( ActionInvocation actionInvocation ) throws Exception { Object userToken = session.get( Struts2PortfolioConstants.USER ); if ( !( userToken instanceof User ) ) session.remove (Struts2PortfolioConstants.USER ) ; User user = (User) session.get( Struts2PortfolioConstants.USER ); if (user == null) { return Action.LOGIN; } else { Action action = ( Action ) actionInvocation.getAction(); if (action instanceof UserAware) { ((UserAware)action).setUser(user); } System.out.println("Logged in: interceptor"); return actionInvocation.invoke(); } }

 

struts.xml
<interceptors>
  <interceptor name="authenticationInterceptor" class="book.four.utils.AuthenticationInterceptor" />
    <interceptor-stack name="secureStack">
      <interceptor-ref name="authenticationInterceptor" />
      <interceptor-ref name="defaultStack" />
    interceptor-stack>
  interceptors>
<default-interceptor-ref name="secureStack" />

<global-results>
  <result name="login" type="redirect">
                /bookFour/LoginForm.action
  result>
  <result name="error">/bookFour/Error.jspresult>
global-results>

上面的代码片段节选自书中的源代码,action instanceof UserAware看起来怪怪的,Struts2PortfolioConstants.USER是一个常量“User”

 

说明:

我们可以看到AuthenticationInterceptor在获得usertoken为空时直接返回一个自己的Result字段,这个字段在xml文件中被定义为了global-results,即全局Result,大家都可以使用而非特定的action

return actionInvocation.invoke(),递归调用通知下一个拦截器

xml中的中定义了一个新的拦截器栈secureStack,并把它设为了默认,它由我们自定义的authenticationInterceptor和default构成,如前文所说,使用defaultStack的前提是你的package继承了struts-default包

 

后记-

第四章主要就是讲拦截器的工作流程和原理,自定义了一个拦截器,唯一迷得地方就是在定义拦截器中action instanceof UserWare这一定,运行代码尝试了半天并没有发现有什么用,一直都是false。。。

 

你可能感兴趣的:([Struts2 in action 笔记3]坐享其成的拦截器(栈))