首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

设计 REST 风格的 MVC 框架-4 设计拦截器

设计 REST 风格的 MVC 框架-4 设计拦截器

设计拦截器拦截器和 Servlet 规范中的 Filter 非常类似,不过 Filter 的作用范围是整个 HttpServletRequest 的处理过程,而拦截器仅作用于 Controller,不涉及到 View 的渲染,在大多数情况下,使用拦截器比 Filter 速度要快,尤其是绑定数据库事务时,拦截器能缩短数据库事务开启的时间。
拦截器接口 Interceptor 定义如清单 18 所示。
清单 18. 定义 Interceptor
1
2
3
public interface Interceptor {
    void intercept(Execution execution, InterceptorChain chain) throws Exception;
}




和 Filter 类似,InterceptorChain 代表拦截器链。InterceptorChain 定义如清单 19 所示。
清单 19. 定义 InterceptorChain
1
2
3
public interface InterceptorChain {
    void doInterceptor(Execution execution) throws Exception;
}




实现 InterceptorChain 要比实现 FilterChain 简单,因为 Filter 需要处理 Request、Forward、Include 和 Error 这 4 种请求转发的情况,而 Interceptor 仅拦截 Request。当 MVC 框架处理一个请求时,先初始化一个拦截器链,然后,依次调用链上的每个拦截器。请参考清单 20 所示的代码。
清单 20. 实现 InterceptorChain 接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class InterceptorChainImpl implements InterceptorChain {
    private final Interceptor[] interceptors;
    private int index = 0;
    private Object result = null;

    InterceptorChainImpl(Interceptor[] interceptors) {
        this.interceptors = interceptors;
    }

    Object getResult() {
        return result;
    }

    public void doInterceptor(Execution execution) throws Exception {
        if(index==interceptors.length)
            result = execution.execute();
        else {
            // must update index first, otherwise will cause stack overflow:
            index++;
            interceptors[index-1].intercept(execution, this);
        }
    }
}




成员变量 index 表示当前链上的第 N 个拦截器,当最后一个拦截器被调用后,InterceptorChain 才真正调用 Execution 对象的 execute() 方法,并保存其返回结果,整个请求处理过程结束,进入渲染阶段。清单 21 演示了如何调用拦截器链的代码。
清单 21. 调用拦截器链
1
2
3
4
5
6
7
8
9
10
class Dispatcher  {
    ...
    private Interceptor[] interceptors;
    void handleExecution(Execution execution, HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
        InterceptorChainImpl chains = new InterceptorChainImpl(interceptors);
        chains.doInterceptor(execution);
        handleResult(request, response, chains.getResult());
    }
}




当 Controller 方法被调用完毕后,handleResult() 方法用于处理执行结果。
返回列表