乍看起来作用差不多,其实它们区别还是挺大的。过滤器是web容器里的东西,拦截器是spring容器里的东西。具体可以从这几点来看下它们之间的不同:
1、规范框架:过滤器使用Servlet规范;拦截器使用的是Spring框架
2、应用范围:被规范约束,过滤器只能在web容器中;基于Spring框架,拦截器既可以用于web容器,也可以用于其他应用;
3、实现原理:过滤器使用函数回调;拦截器使用Spring切面(AOP);
4、应用粒度:过滤器在Servlet业务逻辑处理的前和后加入定制处理;拦截器在http请求的前和后加入定制处理,基于AOP还能细化到方法级;
以上4点基本已经道出了它们的不同。至于它们的关联之处,在于包含关系,从web容器的角度来看,是过滤器的使用方法大于拦截器。很明显,拦截器的应用粒度更小,自然是被粒度更粗的过滤器所包含。针对一个web请求,可以这样看:http请求 -> 过滤器(Servlet前) -> service(Servlet中)-> 拦截器preHandle(Controller前)-> Controller -> 拦截器postHandle(Controller中)-> 拦截器afterCompletion(Controller后)-> 过滤器(Servlet后)。
下面先看一个过滤器,再看怎么用拦截器改写:
过滤器:web.xml
<filter> <filter-name>EnvironmentFilter</filter-name> <filter-class> com.huawei.portalFrame.framework.baseFrame.filter.EnvironmentFilter </filter-class> </filter> <filter-mapping> <filter-name>EnvironmentFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping>
实现类:
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 过滤所有请求,做为当前请求的环境:包括include、forward等 * */ public class EnvironmentFilter implements Filter { public static final ThreadLocal<Environment> environment = new ThreadLocal<Environment>(); public void destroy() { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { environment.remove(); Environment myEnv = new Environment(); myEnv.setRequest((HttpServletRequest)req); myEnv.setResponse((HttpServletResponse)resp); environment.set(myEnv); chain.doFilter(req, resp); } public void init(FilterConfig arg0) throws ServletException { } }
拦截器:spring-mvc.xml
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <mvc:exclude-mapping path="**/f"/> <bean class="cn.migu.newportal.util.http.EnvironmentInterceptor" /> </mvc:interceptor> </mvc:interceptors>
实现类:
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import cn.wlf.util.bean.common.Environment; import cn.wlf.util.threadlocal.ThreadLocalUtils; /** * 初始化本地线程环境变量拦截器 * */ public class EnvironmentInterceptor implements HandlerInterceptor { /** 日志对象 */ private static Logger logger = LoggerFactory.getLogger(EnvironmentInterceptor.class.getName()); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { logger.debug("EnvironmentFilter.doFilter requesturl:{}",request.getRequestURL()); ThreadLocalUtils.getInstance().delEnvironment(); Environment myEnv = new Environment(); myEnv.setRequest((HttpServletRequest)request); myEnv.setResponse((HttpServletResponse)response); ThreadLocalUtils.getInstance().setEnvironment(myEnv); return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3) throws Exception { // TODO Auto-generated method stub } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { // TODO Auto-generated method stub } }