Dorado 9 : 06. 定义全局拦截器

定义拦截器类

以下将要介绍的各种拦截器,其Java Bean的定义方法都是一样。

dorado在此处直接利用了AOP的接口——org.aopalliance.intercept.MethodInvocation,同时dorado还提供了一个可支持更多拦截选项的抽象类——com.bstek.dorado.common.proxy.PatternMethodInterceptor。示例如下:

public class TestViewServiceInterceptor extends PatternMethodInterceptor {
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        // your code
        return methodInvocation.proceed(); // 调用系统默认的处理机制
    }
}

继承自PatternMethodInterceptor的拦截器支持以下3中额外的选项:

  • order - 拦截优先级,数字越小越先被触发,系统默认的order是999。
  • pattern - 要拦截的范围,可使用通配符,不定义则表示全部拦截。
  • excludePattern - 不拦截的范围,可使用通配符。

 

dorado在计算某拦截器的拦截范围时匹配规则时会首先计算pattern,然后再减去其中符合excludePattern的部分。

注册Ajax类操作拦截器

Ajax类操作拦截器用于拦截dorado中的各种Ajax类操作,目前系统中存在的Ajax类操作包含如下几种:

  • load-data: 装载数据,即由前台发起的访问后台DataProvider的操作。
  • load-datatype: 装载DataType的信息(通常系统内部使用)。
  • resolve-data: 提交数据,即由前台发起的访问后台DataResolver的操作。
  • remote-service: Ajax调用,即由前台AjaxAction、AjaxValidator等发起的访问后台ExposedService的操作。

在Spring配置中按照下面的方法配置您声明好的拦截器Bean:

<bean parent="dorado.viewServiceInterceptorRegister">
    <property name="methodInterceptor">
        <!-- 注册一个简单的拦截器 -->
        <bean class="test.TestViewServiceInterceptor1" />
    </property>
</bean>
     
<bean parent="dorado.viewServiceInterceptorRegister">
    <property name="methodInterceptor">     
        <!-- 注册的同时指定更多的信息,只有继承PatternMethodInterceptor的拦截器才支持这些额外的属性 -->
        <bean class="test.TestViewServiceInterceptor2" >
            <property name="order" value="1" /> <!-- 拦截优先级 -->
            <property name="pattern" value="*" /> <!-- 要拦截哪一类Ajax操作 -->
            <property name="excludePattern" value="load-*" /> <!-- 不拦截哪一类Ajax操作 -->
        </bean>
    </property>
</bean>

如果您正在为RemoteService定义拦截器,建议您从com.bstek.dorado.view.service.AbstractRemoteServiceMethodInterceptor继承来实现自己的拦截类,通过该类您可以获得当前被拦截的RemoteService的名称。

定义全局DataProvider拦截器

DataProvider拦截器可以拦截所有的DataProvider的getResult方法。

<bean parent="dorado.dataProviderInterceptorRegister">
    <property name="methodInterceptor">
        <bean class="test.TestDataProviderInterceptor1">
            <property name="excludePattern" value="public-*" /> <!-- 不拦截名称前缀为public-的DataProvider -->
        </bean>
    </property>
</bean>

此处的test.TestDataProviderInterceptor1建议从com.bstek.dorado.data.provider.AbstractDataProviderGetResultMethodInterceptor继承。AbstractDataProviderGetResultMethodInterceptor帮助您忽略掉DataProvider中getResult()和getPagingResult()之外的方法调用,同时此种拦截类还提供了更多的预设参数也可以在很大程度上帮你简化拦截代码。

定义全局DataResolver拦截器

DataResolver拦截器可以拦截所有的DataResolver的resolve方法。

<bean parent="dorado.dataResolverInterceptorRegister">
    <property name="methodInterceptor">
        <bean class="test.TestDataResolverInterceptor">
            <property name="excludePattern" value="public-*" /> <!-- 不拦截名称前缀为public-的DataResolver -->
        </bean>
    </property>
</bean>

此处的test.TestDataResolverInterceptor建议从com.bstek.dorado.data.resolver.AbstractDataResolverMethodInterceptor继承。此种拦截类提供了更多的预设参数可以在很大程度上帮你简化拦截代码。

超时处理参考范例


app-context.xml中添加一个Ajax交互的拦截器:

 

<bean parent="dorado.viewServiceInterceptorRegister">
    <property name="methodInterceptor">
        <bean class="com.xxx.xxx.system.common.UserSessionViewServiceInterceptor" />
    </property>
</bean>

java参考代码:

 

package com.xxx.xxx.system.common;
 
import javax.servlet.http.HttpServletRequest;
 
import org.aopalliance.intercept.MethodInvocation;
 
import com.bstek.dorado.view.resolver.ClientRunnableException;
import com.bstek.dorado.view.service.AbstractRemoteServiceMethodInterceptor;
import com.bstek.dorado.web.DoradoContext;
 
public class UserSessionViewServiceInterceptor extends AbstractRemoteServiceMethodInterceptor {
 
    @Override
    protected Object invoke(MethodInvocation invocation, String serviceName) throws Throwable {
        HttpServletRequest request  = DoradoContext.getCurrent().getRequest();
        Object user = request.getSession().getAttribute("userObject");
        if (null==user){
            throw new ClientRunnableException("Session超时","window.top.location.href='./index.html';");
        }
        Object object = invocation.proceed();//调用默认的ajax服务
        return object;
    }
}

 

其中ClientRunnableException的第二个参数可以设置为一段script脚本,最终这段脚本在客户端会被eval()函数执行,便于你做重新登录或跳转到登录页面之类的相关操作。