过滤器和拦截器的区别

  乍看起来作用差不多,其实它们区别还是挺大的。过滤器是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
        
    }
    
   
}

 

posted on 2018-06-29 18:14  不想下火车的人  阅读(240)  评论(0编辑  收藏  举报

导航