SpringBoot拦截器(Interceptor)与过滤器(Filter)的使用说明

拦截器与过滤器的区别

1、拦截器是基于java的反射机制的,而过滤器是基于函数回调。

2、拦截器不依赖与servlet容器,过滤器依赖与servlet容器。

3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。

5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

6、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用。而过滤器只需依赖servlet api,不需要依赖spring。

何时使用拦截器?何时使用过滤器?

  • 如果是非spring项目,那么拦截器则不可使用,只能使用过滤器
  • 如果是处理controller前后,则既可以使用拦截器也可以使用过滤器
  • 如果是处理dipaterServlet前后,则只可以使用过滤器,像中文乱码问题通常都是使用过滤器实现的

拦截器与过滤器的一个关系图

整个执行流程如下所示:

过滤器的使用

过滤器的触发时机是容器后,servlet之前,所以过滤器的doFilter(ServletRequest request, ServletResponse response, FilterChain chain)的入参是ServletRequest ,而不是httpservletrequest。因为过滤器是在httpservlet之前

//过滤器处理乱码
@Component
public class CharacterEncodingFilter implements Filter {
    //web服务器启动,就会初始化,因为它要随时等待监听
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化");
    }
    //当访问网页时,就会进行过滤,每访问一次,就会过滤一次
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=UTF-8");
        System.out.println("解码前");
        filterChain.doFilter(servletRequest,servletResponse);  
        System.out.println("解码后");
    }
    //只有当web服务器关闭时,才会销毁
    @Override
    public void destroy() {
        System.out.println("销毁");
    }
}

拦截器的使用

在springboot项目中拦截器的定义和使用。springboot是依靠springMVC来完成的。springMVC提供了一个HandlerInterceptor接口,用于表示定义一个拦截器。受限制自定义个类,在这个类实现这个接口。

public class MyIntercepetor implements HandlerInterceptor {
  /**
   * return ture;  执行下一个拦截器,放行
   * return false; 不执行下一个拦截器,不放行
   * 通常也只使用第一行拦截就可以了
   */
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    System.out.println("--------处理前-----------");
    return true;
  }
  //后面两行不使用可以删除掉
  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

  }

  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

  }
}

具体使用:拦截请求

//定义一个拦截器,检测session对象中是否有指定内容
public class LoginHandlerInterceptor implements HandlerInterceptor
{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //判断是否已登录
        Object user = request.getSession().getAttribute("LoginUser");

        //若无登录,跳转至登录页面
        if (user == null) {
            request.setAttribute("key", "您没有权限,请先登录");
            request.getRequestDispatcher("/login").forward(request, response);
            return false;
        } else {
            return true;
        }
    }
}

借助WebMvcConfigure接口,可以将用户定义的拦截器进行注册,才可以保证拦截器能够生效和使用。定义一个类,然后让这个类实现WebMvcConfigure接口。

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    //拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginHandlerInterceptor())
                .addPathPatterns("/**") //拦截所有请求
                //排除拦截的内容,登录页面和注册页面的相关请求都排除掉
                .excludePathPatterns("/", "/login", "/register", "/regist", "/loginIn", "/css/**", "/js/**", "/img/**");
    }
}

 

posted @ 2022-05-07 15:23  RFAA  阅读(1187)  评论(0编辑  收藏  举报