在Web应用中,常常存在拦截全部或部分请求进行统一处理的应用场景,如权限校验、参数校验、性能监控等。 在SpringMVC框架中,我们可以通过过滤器或拦截器实现相关功能,spring-boot-starter-web模块底层实际就是SpringMVC框架,那么在SpringBoot项目中如何使用过滤器或拦截器呢?
  
  过滤器与拦截器的区别
  
  项目 过滤器Filter 拦截器Interceptor 说明
  
  规范定义 Servlet规范中定义,与SpringMVC框架无关。 SpringMVC提供组件之一。 过滤器不依赖于Spring MVC框架。
  
  调用顺序 在Spring DispatchServlet执行前 在Spring DispatchServlet中调用 故过滤器执行会在拦截器之前。
  
  容器资源 无法使用Spring容器资源,如果需要使用,可以通过ApplicationContext上下文对象获取 拦截器本身就是Spring的容器资源,可以通过Ioc进行依赖注 入直接使用容器资源。
  
  过滤器与拦截器的使用
  
  创建项目
  
  创建一个maven项目spring-boot-examples-intercept,添加一下依赖:
  
  <dependencies>
  
  <dependency>
  
  <groupId>org.springframework.boot</groupId>
  
  <artifactId>spring-boot-starter-web</artifactId>
  
  </dependency>
  
  <dependency>
  
  <groupId>org.projectlombok</groupId>
  
  <artifactId>lombok</artifactId>
  
  </dependency>
  
  </dependencies>
  
  添加业务接口
  
  添加一个HelloController类,实现一个Restful的测试接口/hello,代码如下:
  
  @RestController
  
  @Slf4j
  
  public class HelloController {
  
  /**
  
  * 测试请求方法
  
  *
  
  * @return
  
  */
  
  @GetMapping("/hello")
  
  public String hello() {
  
  log.info("[{}]执行{}方法!", this.getClass().getSimpleName(), "hello");
  
  return "Hello!";
  
  }
  
  }
  
  添加过滤器
  
  过滤器开发
  
  添加第一个过滤器FirstFilter类,实现Filter接口,代码如下:
  
  @Slf4j
  
  public class FirstFilter implements Filter {
  
  /**
  
  *
  
  * @param servletRequest
  
  * @param servletResponse
  
  * @param filterChain
  
  * @throws IOException
  
  * @throws ServletException
  
  */
  
  @Override
  
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  
  log.info("[{}]执行{}方法:Before!", this.getClass(www.jiahuayulpt.com).getSimpleName(), "doFilter");
  
  //执行下一个filter
  
  filterChain.doFilter(servletRequest, servletResponse);
  
  log.info("[{}]执行{}方法:After!", this.getClass().getSimpleName(), "doFilter");
  
  }
  
  }
  
  添加第二个过滤器SecondFilter类,实现Filter接口,代码如下:
  
  @Slf4j
  
  public class SecondFilter implements Filter {
  
  /**
  
  * @param servletRequest
  
  * @param servletResponse
  
  * @param filterChain
  
  * @throws IOException
  
  * @throws ServletException
  
  */
  
  @Override
  
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  
  log.info("[{}]执行{}方法:Before!", this.getClass().getSimpleName(), "doFilter");
  
  //执行下一个filter
  
  filterChain.doFilter(servletRequest, servletResponse);
  
  log.info("[{}]执行{}方法:After!", this.getClass().getSimpleName(), "doFilter");
  
  }
  
  }
  
  过滤器配置
  
  配置过滤器有两种方式,分别是通过配置类或者注解的方式,两种方式都可以将过滤器配置到服务中,但是通过注解的方式我还没发现指定过滤器顺序的方法(通过@Order注解是无效的),所以如果需要指定过滤器执行顺序的,建议使用方式一,否则使用方式二代码更简洁。
  
  方式一:通过配置类配置过滤器。 添加一个Spring Boot的配置类FilterConfig,里面注册两个FilterRegistrationBean类型的Bean,代码如下:
  
  @Configuration
  
  public class FilterConfig {
  
  /**
  
  * 注册第一个过滤器
  
  * @return
  
  */
  
  @Bean
  
  public FilterRegistrationBean firstFilter(www.huarenyl.cn) {
  
  FilterRegistrationBean registrationBean = new FilterRegistrationBean(new FirstFilter());
  
  //可不设置,默认过滤路径即为:/*
  
  registrationBean.addUrlPatterns("/*");
  
  registrationBean.setOrder(1);
  
  return registrationBean;
  
  }
  
  /**
  
  * 注册第二个过滤器
  
  * @return
  
  */
  
  @Bean
  
  public FilterRegistrationBean secondFilter(www.yongshi123.cn) {
  
  FilterRegistrationBean registrationBean = new FilterRegistrationBean(new SecondFilter());
  
  //可不设置,默认过滤路径即为:/*
  
  registrationBean.addUrlPatterns("/*");
  
  registrationBean.setOrder(2);
  
  return registrationBean;
  
  }
  
  }
  
  方式二:通过注解配置过滤器 在FirstFilter和SecondFilter类上分别添加注解配置@WebFilter(urlPatterns = "/*"),由于@WebFilter并不是Spring提供的注解,所以还需要在项目的启动类中添加注解配置@ServletComponentScan,告诉Spring扫描路径,如下:
  
  @SpringBootApplication
  
  @ServletComponentScan(basePackages = "org.cent.springboot.example.intercept.filter")
  
  public class Application {
  
  public static void main(String[] args) {
  
  SpringApplication.run(Application.class, args);
  
  }
  
  }
  
  添加拦截器
  
  开发拦截器
  
  添加第一个拦截器FirstInterceptor类,实现HandlerInterceptor接口,代码如下:
  
  @Slf4j
  
  public class FirstInterceptor implements HandlerInterceptor {
  
  /**
  
  * controller方法调用前调用。
  
  *
  
  * @param request
  
  * @param response
  
  * @param handler
  
  * @return 往下执行则返回true,否则返回false
  
  * @throws Exception
  
  */
  
  @Override
  
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  
  log.info("[{}]执行{}方法!", this.getClass(www.dfgjpt.com).getSimpleName());
  
  return true;
  
  }
  
  /**
  
  * controller方法调用后视图渲染前执行。
  
  *
  
  * @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("[{}]执行{}方法!", this.getClass().getSimpleName(), "postHandle");
  
  }
  
  /**
  
  * controller方法调用且视图渲染完成后执行
  
  *
  
  * @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("[{}]执行{}方法!", this.getClass().getSimpleName(), "afterCompletion");
  
  }
  
  添加第二个拦截器SecondInterceptor类,实现HandlerInterceptor接口,代码如下:
  
  @Slf4j
  
  public class SecondInterceptor implements www.tiaotiaoylzc.com HandlerInterceptor {
  
  /**
  
  * controller方法调用前调用。
  
  *
  
  * @param request
  
  * @param response
  
  * @param handler
  
  * @return 往下执行则返回true,否则返回false
  
  * @throws Exception
  
  */
  
  @Override
  
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  
  log.info("[{}]执行{}方法!", this.getClass(www.dasheng178.com).getSimpleName(www.yongshiyule178.com/), "preHandle");
  
  return true;
  
  }
  
  /**
  
  * controller方法调用后视图渲染前执行。
  
  *
  
  * @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("[{www.fengshen157.com}]执行{}方法!", this.getClass().getSimpleName(), "postHandle");
  
  }
  
  /**
  
  * controller方法调用且视图渲染完成后执行
  
  *
  
  * @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("[{}]执行{}方法!",www.yihuanyule.cn this.getClass(www.jiuzhoyulpt.cn).getSimpleName(), "afterCompletion");
  
  }
  
  配置拦截器
  
  添加一个Spring Boot配置类,实现WebMvcConfigurer接口以覆盖容器默认配置,代码如下:
  
  @Configuration
  
  public class InterceptorConfig implements WebMvcConfigurer {
  
  /**
  
  * 重写添加拦截器方法
  
  *
  
  * @param registry
  
  */
  
  @Override
  
  public void addInterceptors(InterceptorRegistry registry) {
  
  registry.addInterceptor(new FirstInterceptor())
  
  .addPathPatterns("/**")
  
  .order(1);//指定执行顺序,数值越小越优先
  
  registry.addInterceptor(new SecondInterceptor())
  
  .addPathPatterns("/hello")
  
  .order(2);//指定执行顺序,数值越小越优先

  过滤器依赖于Servlet容器,而Interceptor则为SpringMVC的一部分。过滤器能够拦截所有请求,而Interceptor只能拦截Controller的请求,所以从覆盖范围来看,Filter应用更广一些。但是在Spring逐渐一统Java框架、前后端分离越演越烈,实际上大部分的应用场景,拦截器都可以满足了。

SpringBoot入坑指南之六:使用过滤器或拦截器的更多相关文章

  1. springBoot之配置文件的读取以及过滤器和拦截器的使用

    前言 在之前的学习springBoot中,成功的实现了Restful风格的基本服务.但是想将之前的工程作为一个项目来说,那些是仅仅不够的.可能还需要获取自定义的配置以及添加过滤器和拦截器.至于为什么将 ...

  2. SpringBoot入坑-项目搭建

    对于学过三大框架的小童鞋,从今天开始给大家带来一套新的框架学习,相信对于做程序的小童鞋一定有所耳闻,作为下一代java开发框架springboot,减去了繁琐的xml配置,相信用过spring.sta ...

  3. electron入坑指南

    electron入坑指南 简介 electron 实际集成chrome浏览器和node环境, 运行你写的网页 app 基本目录结构 index.html 名称可以不是index, 这个文件与普通网页的 ...

  4. C语言入坑指南-被遗忘的初始化

    前言 什么是初始化?为什么要初始化?静态变量和局部变量的初始化又有什么区别?实际应用中应该怎么做?本文将一一回答这些问题. 什么是初始化 初始化指的是对数据对象或者变量赋予初始值.例如: int va ...

  5. Elasticsearch入坑指南之RESTful API

    Elasticsearch入坑指南之RESTful API Tags:Elasticsearch ES为开发者提供了非常丰富的基于Http协议的Rest API,通过简单的Rest请求,就可以实现非常 ...

  6. ElasticSearch入坑指南之概述及安装

    ---恢复内容开始--- ElasticSearch入坑指南之概述及安装 了解ElasticSearch ElasticSearch(简称ES)基于Lucene的分布式全文检索引擎.使用ES可以实现近 ...

  7. eclipse中导入外部包却无法查看对应源码或Javadoc的入坑指南

    eclipse中导入外部包却无法查看对应源码或Javadoc的 入坑指南 出现这个错误的原因是,你虽然导入了.jar包,但没有配置对应的Javadoc或源码路径,所以在编辑器中无法查看源 码和对应AP ...

  8. Rust入坑指南:核心概念

    如果说前面的坑我们一直在用小铲子挖的话,那么今天的坑就是用挖掘机挖的. 今天要介绍的是Rust的一个核心概念:Ownership.全文将分为什么是Ownership以及Ownership的传递类型两部 ...

  9. Rust入坑指南:鳞次栉比

    很久没有挖Rust的坑啦,今天来挖一些排列整齐的坑.没错,就是要介绍一些集合类型的数据类型."鳞次栉比"这个标题是不是显得很有文化? 在Rust入坑指南:常规套路一文中我们已经介绍 ...

随机推荐

  1. CAN-bus接口控制实验

    CAN-bus接口控制实验 2016-04-12 20:38:41来源: eefocus 关键字:CAN  bus  接口控制   收藏 评论(0) 分享到 微博 QQ 微信 LinkedIn 一.实 ...

  2. 2017-2018 Exp7 网络欺诈技术防范 20155214

    目录 Exp7 网络欺诈技术防范 实验内容 信息收集 知识点 Exp7 网络欺诈技术防范 实验内容 实验环境 主机 Kali 靶机 Windows 10 实验工具 平台 Metaploit 信息收集 ...

  3. Exp9 Web安全基础实践

    Exp9 Web安全基础实践 基础问题回答 1.SQL注入攻击原理,如何防御? 对用户的输入进行校验,可以通过正则表达式,双"-"进行转换等. 不要使用动态拼装sql,可以使用参数 ...

  4. 20155308『网络对抗技术』Exp5 MSF基础应用

    20155308『网络对抗技术』Exp5 MSF基础应用 一.原理与实践说明 实践内容 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: 一个主动攻击实 ...

  5. 28 个 C/C++ 开源 JSON 程序库性能及标准符合程度评测

    28 个 C/C++ 开源 JSON 程序库性能及标准符合程度评测 坊间有非常多的 C/C++ JSON 库,怎么选择是一个难题. [nativejson-benchmark](https://git ...

  6. stl源码剖析 详细学习笔记deque(1)

    //--------------------------15/3/12---------------------------- deque { deque没有容量(capacity)观念,是动态分段的 ...

  7. 转 ssh-keygen 的 详解

    为了让两个linux机器之间使用ssh不需要用户名和密码.所以采用了数字签名RSA或者DSA来完成这个操作. 模型分析 假设 A (192.168.20.59)为客户机器,B(192.168.20.6 ...

  8. 机器学习英雄访谈录之 Kaggle Kernels 专家:Aakash Nain

    目录 机器学习英雄访谈录之 Kaggle Kernels 专家:Aakash Nain 正文 对我的启发 机器学习英雄访谈录之 Kaggle Kernels 专家:Aakash Nain Sanyam ...

  9. Apache Ignite 学习笔记(四): Ignite缓存冗余备份策略

    Ignite的数据网格是围绕着基于内存的分布式key/value存储能力打造的.当初技术选型的时候,决定用Ignite也是因为虽然同样是key/value存储,它有着和其他key/value存储系统不 ...

  10. Flink standalone模式作业执行流程

    宏观流程如下图: client端 生成StreamGraph env.addSource(new SocketTextStreamFunction(...)) .flatMap(new FlatMap ...