Springboot拦截器的介绍、使用、拦截器与过滤器的区别

目录

一、什么是拦截器、拦截器的功能?

二、拦截器与过滤器的区别

2.1、出身不同:

2.2、使用场景不同:

2.3、触发时机不同: 

2.4、实现不同:

三、拦截器在springboot中如何使用

 3.1 定义拦截器:

  3.2 注册拦截器:

3.3 指定拦截规则:

四、过滤器的使用举例:

 五、参考资料:


一、什么是拦截器、拦截器的功能?

     拦截器Interceptor同 Filter 过滤器一样,它俩都是面向切面编程——体现了AOP的编程思想 ,拦截器可以根据 URL 对请求进行拦截,主要应用于登陆校验、日志记录、权限验证、性能监控等功能:

   ● 登录校验:判断用户是否登录。

   ● 日志记录:记录请求操作日志(用户ip,访问时间等),以便统计请求访问量。

   ● 权限检查:用户是否有权限访问资源,如校验token

   ● 性能监控:通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间,即监控请求处理时长等。

   ● 通用行为:读取 Cookie 得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取 Locale、Theme 信息等,只要是多个处理器都需要的即可使用拦截器实现。

二、拦截器与过滤器的区别

   过滤器 和 拦截器均体现了AOP的编程思想,都可以实现诸如日志记录、登录校验、权限验证等功能,但二者的不同点也是比较多的。

  • 2.1、出身不同:
  • 拦截器实现的是HandlerInterceptor接口,拦截器是属于Spring技术,它是Spring的一个组件,并由Spring容器创建管理,并不依赖Tomcat服务器,是可以单独使用的,拦截器不仅能应用在web程序中,也可以用于ApplicationSwing等程序中;过滤器实现是 javax.servlet.Filter 接口,而这个接口是在Servlet规范中定义的,也就是说过滤器Filter 的使用要依赖于Tomcat服务器Filter 是在Tomcat服务器创建的对象,导致它只能在web程序中使用。

  • 2.2、使用场景不同:
  • 过滤器侧重于对请求参数进行过滤的, 比如敏感词过滤、字符集编码设置CharacterEncodingFilter、修改请求头和响应头的信息;拦截器是侧重于验证请求、截断请求,对用户请求做预先的判断处理、可以修改ModelAndView对象中的数据和视图,影响控制器方法最终的执行结果的,拦截器主要应用于登陆校验、日志记录、权限验证、性能监控等功能:

  • 2.3、触发时机不同: 
  • 过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。

    拦截器 Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。

  • 过滤器几乎可以对所有进入容器的请求起作用,而拦截器只会对Controller中请求或访问static目录下的资源请求起作用。

  • 2.4、实现不同:
  • 过滤器是基于方法回调实现的,当我们要执行下一个过滤器或下一个流程时,需要调用 FilterChain 对象的 doFilter 方法进行回调执行,如下图所示:

  • 拦截器是基于动态代理(底层是反射)实现的。

三、拦截器在springboot中如何使用

   拦截器它是链式调用,一个应用中可以同时存在多个拦截器Interceptor ,一个请求也可以触发多个拦截器 ,而每个拦截器的调用会依据它的声明顺序依次执行。

在 Spring Boot 项目中,使用拦截器功能通常需要以下 3 步:

  1. 定义拦截器;
  2. 注册拦截器;
  3. 指定拦截规则(如果是拦截所有,静态资源也会被拦截)。

 3.1 定义拦截器:

   创建一个普通类,并实现 HandlerInterceptor 接口,

   然后实现HandlerInterceptor 接口中的 3 个方法:

返回值类型方法声明描述
boolean

preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 

(请求对象、响应对象、被拦截的控制器对象)

该方法在控制器处理请求方法前执行,其返回值表示是否中断后续操作,返回 true 表示继续向下执行,返回 false 表示中断后续操作。
voidpostHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)该方法在控制器方法执行完之后、解析视图之前执行的,可以通过此方法对请求域中的数据和视图做进一步修改,可以对执行结构进行二次修正。
voidafterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)该方法在视图渲染结束后执行,也就是请求处理完成之后,可以通过此方法实现资源清理、记录日志信息等工作。
package net.biancheng.www.componet;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 目标方法执行前
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object loginUser = request.getSession().getAttribute("loginUser");
        if (loginUser == null) {
            //未登录,返回登陆页
            request.setAttribute("msg", "您没有权限进行此操作,请先登陆!");
            request.getRequestDispatcher("/index.html").forward(request, response);
            return false;
        } else {
            //放行
            return true;
        }
    }

    /**
     * 目标方法执行后
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("postHandle执行{}", modelAndView);
    }

    /**
     * 页面渲染后
     *
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("afterCompletion执行异常{}", ex);
    }
}
  3.2 注册拦截器:

    创建一个实现了 WebMvcConfigurer 接口的配置类(使用了 @Configuration 注解的类),重写 addInterceptors() 方法,并在该方法中调用 registry.addInterceptor() 方法将自定义的拦截器注册到容器中。

     在配置类 MyMvcConfig 中,添加以下方法注册拦截器,代码如下:

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    ......
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor());
    }
}
3.3 指定拦截规则:
@Slf4j
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    ......
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        log.info("注册拦截器");
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**") //拦截所有请求,包括静态资源文件
                .excludePathPatterns("/", "/login", "/index.html", "/user/login", "/css/**", "/images/**", "/js/**", "/fonts/**"); //放行登录页,登陆操作,静态资源
    }
}

在指定拦截器拦截规则时,调用了两个方法,这两个方法的说明如下:

  • addPathPatterns:该方法用于指定拦截路径,例如拦截路径为“/**”,表示拦截所有请求,包括对静态资源的请求。
  • excludePathPatterns:该方法用于排除拦截路径,即指定不需要被拦截器拦截的请求。

四、过滤器的使用举例:

   字符集编码设置举例:CharacterEncodingFilter类实现了Filter接口,并重写了doFilter方法。在这个方法中,我们将请求和响应的字符编码设置为UTF-8:

@Component
public class CharacterEncodingFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);
    }
}

 五、参考资料:

1、http://t.csdnimg.cn/rs1ji

2、http://t.csdnimg.cn/JBmez

3、http://t.csdnimg.cn/PM8up

4、Spring Boot拦截器精讲

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值