zoukankan      html  css  js  c++  java
  • WebWork教程 Interceptor(拦截器)

    Interceptor(拦截器)将Action共用的行为独立出来,在Action执行前后运行。这也就是我们所说的AOPAspect Oriented Programming,面向切面编程),它是分散关注的编程方法,它将通用需求功能从不相关类之中分离出来;同时,能够使得很多类共享一个行为,一旦行为发生变化,不必修改很多类,只要修改这个行为就可以。
     
    Interceptor将很多功能从我们的Action中独立出来,大量减少了我们Action的代码,独立出来的行为具有很好的重用性。XWorkWebWork的许多功能都是有Interceptor实现,可以在配置文件中组装Action用到的Interceptor,它会按照你指定的顺序,在Action执行前后运行。Interceptor在框架中的应用如下图所示
     
     
    当你提交对Aciton(默认是.action结尾的Url)的请求时,ServletDispatcher会根据你的请求,去调度并执行相应的Action。在Action执行之前,调用被 Interceptor截取,InterceptorAction执行前后运行。
     
    我们在用户注册的例子中就使用了取得Request请求参数的拦截器,配置文件中<interceptor-ref name="params"/>将拦截器params组装到RegisterAction中。“params”在我们的webwork-default.xml配置文件中有定义,webwork-default.xml中拦截器的定义如下:
     
    <interceptors>
                <interceptor name="timer" class="com.opensymphony.xwork.interceptor.TimerInterceptor"/>
                <interceptor name="logger" class="com.opensymphony.xwork.interceptor.LoggingInterceptor"/>
                <interceptor name="chain" class="com.opensymphony.xwork.interceptor.ChainingInterceptor"/>
                <interceptor name="static-params" class="com.opensymphony.xwork.interceptor.StaticParametersInterceptor"/>
                <interceptor name="params" class="com.opensymphony.xwork.interceptor.ParametersInterceptor"/>
                <interceptor name="model-driven" class="com.opensymphony.xwork.interceptor.ModelDrivenInterceptor"/>
                <interceptor name="component" class="com.opensymphony.xwork.interceptor.component.ComponentInterceptor"/>
                <interceptor name="token" class="com.opensymphony.webwork.interceptor.TokenInterceptor"/>
                <interceptor name="token-session" class="com.opensymphony.webwork.interceptor.TokenSessionStoreInterceptor"/>
                <interceptor name="validation" class="com.opensymphony.xwork.validator.ValidationInterceptor"/>
                <interceptor name="workflow" class="com.opensymphony.xwork.interceptor.DefaultWorkflowInterceptor"/>
                <interceptor name="servlet-config" class="com.opensymphony.webwork.interceptor.ServletConfigInterceptor"/>
                <interceptor name="prepare" class="com.opensymphony.xwork.interceptor.PrepareInterceptor"/>
                <interceptor name="conversionError" class="com.opensymphony.webwork.interceptor.WebWorkConversionErrorInterceptor"/>
                <interceptor-stack name="defaultStack">
                    <interceptor-ref name="static-params"/>
                    <interceptor-ref name="params"/>
                    <interceptor-ref name="conversionError"/>
                </interceptor-stack>
                <interceptor-stack name="validationWorkflowStack">
                    <interceptor-ref name="defaultStack"/>
                    <interceptor-ref name="validation"/>
                    <interceptor-ref name="workflow"/>
                </interceptor-stack>
            </interceptors>
    这些都时有框架提供的默认的Interceptor,下面我来看看Interceptor使用的步骤:
    1、   创建一个自己需要的Interceptor类,它必需实现
    com.opensymphony.xwork.interceptor.Interceptor
    接口,具体的开发见下面的Interceptor的原理。
    2、   在配置文件(xwork..xml)中申明这个Interceptor类,它放在标签<interceptor />中,同是<interceptor />标签嵌入在<interceptors />标签内部。
    3、   创建Interceptor栈,使用标签:<interceptor-stack />让一组Interceptor可以按次序调用。(可选)
    4、   指定Action所要用到的Interceptor(前面申明过的),可以用<interceptor-ref /><default-interceptor-ref />标签。前面的标签指定某个Action所用到的Interceptor,如果Action没有被用<interceptor-ref />指定Interceptor,它将使用<default-interceptor-ref />指定的Interceptor
    框架中给我们提供了很多实用的Interceptor,它的定义上面已经给出,它的具体功能如下:
    l          timer:记录Action执行的时间,并做为日志信息输出;
    l          logger:在日志信息中输出要执行的Action信息;
    l          chain:将前一个执行结束的Action属性设置到当前的Action中。它被用在ResultType为“chain”指定结果的Action中,该结果Action对象会从OgnlValueStack中获得前一个Action对应的属性,它实现Action链之间的数据传递;
    l          static-params:将xwork.xml配置文件里定义的Action参数,设置到对应的Action中。Action参数使用<param />标签,是<action />标签的直接子元素。我们这里定义的Action类必需实现com.opensymphony.xwork.config.entities. Parameterizable接口;
    l          params:将Request请求的参数设置到相应Action对象的属性中,用户注册例子用到过这个拦截器;
    l          model-driven:如果Action实现ModelDriven接口,它将getModel()取得的模型对象存入OgnlValueStack中;
    l          component:激活组件功能支持,让注册过的组件在当前Action中可用,即为Action提供IoC(依赖倒转控制)框架的支持;
    l          token:核对当前Action请求(request)的有效标识,防止重复提交Action请求(request)
    l          token-session:功能同上,但是当提交无效的Action请求标识时,它会将请求数据保存到session中。
    l          validation:实现使用xml配置文件({Action}-validation.xml)对Action属性值进行验证,详细请看后面介绍的验证框架。
    l          workflow:调用Action类的验证功能,假设Action使用ValidationAware实现验证(ActionSupport提供此功能),如果验证没有通过,workflow会将请求返回到input视图(Action<result />中定义的)。
    l          servlet-config:提供Action直接对HttpServletRequestHttpServletResponseJavaServlet api的访问,Action要实现相应的接口,例如:ServletRequestAwareServletResponseAware。如果必需要提供对JavaServlet api的访问,我们建议使用ServletActionContext,在前面ActionContext章节中有介绍。
    l          prepare:在Action执行之前调用Actionprepare()方法,这个方法是用来准备Action执行之前要做的工作。它要求我们的Action必需实现com.opensymphony.xwork. Preparable接口
    conversionError:用来处理框架进行类型转化(Type Conversion)时的出错信息。它将存储在ActionContext中的类型转化(Type Conversion)错误信息转化成相应的Action字段的错误信息,保存在堆栈中。根据需要,可以将这些错误信息在视图中显示出来。
     
    Interceptor的原理
    下面我们来看看Interceptor是如何实现在Action执行前后调用的:
    ActionInterceptor在框架中的执行,是由ActionInvocation对象调用的。它是用方法:String invoke() throws Exception;来实现的,它首先会依次调用Action对应的Interceptor,执行完成所有的Interceptor之后,再去调用Action的方法,代码如下:
    if (interceptors.hasNext()) {
    Interceptor interceptor = (Interceptor) interceptors.next();
    resultCode = interceptor.intercept(this);
    } else {
         if (proxy.getConfig().getMethodName() == null) {
    resultCode = getAction().execute();
    } else {
            resultCode = invokeAction(getAction(), proxy.getConfig());
    }
    }
    它会在拦截器栈中遍历Interceptor,调用Interceptor方法:
    String intercept(ActionInvocation invocation) throws Exception;
    我们一直都提到,Interceptor是在Action前后执行,可是从上面的代码我们看到的却是执行完所有Interceptorintercept()方法之后再去调用我们的Action。“在Action前后执行”是如何实现的呢?我们来看看抽象类AroundInterceptorintercept()实现:
    public String intercept(ActionInvocation invocation) throws Exception {
            String result = null;
     
            before(invocation);
            result = invocation.invoke();
            after(invocation, result);
     
            return result;
        }
    原来在intercept()方法又对ActionInvocationinvoke()方法进行递归调用,ActionInvocation循环嵌套在intercept()中,一直到语句result = invocation.invoke();执行结束,即:Action执行完并返回结果result,这时Interceptor对象会按照刚开始执行的逆向顺序依次执行结束。这样before()方法将在Action执行前调用,after()方法在Action执行之后运行
  • 相关阅读:
    Python—Socket
    python-—计算器
    Python—I-O多路复用
    Python—redis
    《Python数据分析常用手册》一、NumPy和Pandas篇
    python--Selenium-模拟浏览器
    python--selenium简单模拟百度搜索点击器
    关于selenium实现滑块验证
    python 读写、创建 文件的方法(必看)
    Python 爬虫的工具列表大全
  • 原文地址:https://www.cnblogs.com/daxia/p/520499.html
Copyright © 2011-2022 走看看