乍看起来作用差不多,其实它们区别还是挺大的。过滤器是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>HelloFilter</filter-name>
<filter-class>
com.wlf.filter.HelloFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>HelloFilter</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 HelloFilter implements Filter
{
public static final ThreadLocal<Hello> helloThreadLocal = new ThreadLocal<Hello>();
public void destroy()
{
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException,
ServletException
{
helloThreadLocal.remove();
Hello myHello = new Hello();
myEnv.setRequest((HttpServletRequest)req);
myEnv.setResponse((HttpServletResponse)resp);
helloThreadLocal.set(myHello);
chain.doFilter(req, resp);
}
public void init(FilterConfig arg0) throws ServletException
{
}
}
用拦截器改写过滤器,先配置spring:spring-mvc.xml
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="**/f"/>
<bean class="com.wlf.util.http.HelloInterceptor" />
</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 com.wlf.util.bean.common.Hello;
import com.wlf.util.threadlocal.ThreadLocalUtils;
/**
* 初始化本地线程环境变量拦截器
*
*/
public class HelloInterceptor implements HandlerInterceptor
{
/** 日志对象 */
private static Logger logger = LoggerFactory.getLogger(HelloInterceptor.class.getName());
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2)
throws Exception
{
logger.debug("HelloInterceptor.preHandle requesturl:{}",request.getRequestURL());
ThreadLocalUtils.getInstance().delHello();
Hello myHello = new Hello();
myEnv.setRequest((HttpServletRequest)request);
myEnv.setResponse((HttpServletResponse)response);
ThreadLocalUtils.getInstance().setHello(myHello);
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
}
}