Java中的拦截器Interceptor和过滤器filter的区别
为什么要写这篇博客
之前换工作想要了解一下拦截器和过滤器之间的区别,到网上搜索了一下,发现基本博客都是一模一样的,说的我也一知半解,最近在看spring的源码,对Interceptor和filter的区别有了一点自己的看法。只是比较初级的一些见解,想记录一下,如果有其他的观点欢迎一起讨论。
什么是过滤器Filter
过滤器是由servlet 2.3规范定义的一个接口,是针对servlet请求前后做特殊处理的,多个filter可以组成一个请求链。正常的一个filter逻辑都会写在doFilter()里面,在Chain.doFilter()方法之前是对servlet执行之前的数据做处理,之后是返回数据处理。这里不对过滤器做详细的解读。
什么是拦截器Intercept
这里先说一下Spring的工作模式,Spring框架极大简化了传统的servlet&Jsp式的开发模式,SpringMVC中,所有的请求都委托到DispatcherServlet中,DispatcherServlet中根据mappingRegistry(url和controller中得method的映射),找到对应的映射,最后执行Controller中的方法。
Interceptor就是在DispatcherServlet中的doService()方法和执行Controller之间执行的。
相关代码执行路径:
DispatcherServlet#doService
DispatcherServlet#doDispatch
DispatcherServlet#getHandler
AbstractHandlerMapping#getHandler
AbstractHandlerMapping#getHandlerInternal // 这里从mappingRegistry获取对应的method
AbstractHandlerMapping#getHandlerExecutionChain // 这里添加各种HandlerInterceptor
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request, LOOKUP_PATH);
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
else {
chain.addInterceptor(interceptor);
}
}
return chain;
}
补充一下intercept执行代码
...
...
if (!mappedHandler.applyPreHandle(processedRequest, response)) { // 执行intercept的preHandle
return;
}
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 执行真正的方法
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv); // 执行intercept的postHandle
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex); // 发现异常执行afterCompletion方法
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
Filter和Interceptor的不同点
根据上面的解读,我们可以发现Filter是Servlet规范中的技术,是和Servlet配套使用的,具体实现是有容器实现的,比如Tomcat。可以对Http的request和response做过滤,也可以对静态页面做过滤操作。
Interceptor在执行Controller方法前后做了一些钩子函数。可以实现自定义的操作。
至于如何使用还要看实际场景。