服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - springboot整合过滤器实战步骤

springboot整合过滤器实战步骤

2022-11-11 13:16小z♀ Java教程

在项目开发过程中,过滤器或者拦截器几乎是必用的,他可以很方便的完成类似日志处理、token验证等一系列操作,区别于业务接口,独立进行处理,感觉就是一种Aop思想。下面模拟请求接口前的token验证,进行过滤器的实战

下面先建立一个MVC的基本请求接口,如下:

一、普通的接口访问

springboot整合过滤器实战步骤

如上,先新增一个testController。

springboot整合过滤器实战步骤

先用postman测试一下通不通。

springboot整合过滤器实战步骤

结果是通的,准备工作完成。

 

二、增加一个过滤器

下面增加一个过滤器来实现一个接口拦截并处理token校验的模拟。

简单处理,有如下两个步骤。

1、自定义过滤器

springboot整合过滤器实战步骤

package com.example.demo_filter_interceptor.config;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
* @Classname TestFilter
* @Description TODO
* @Date 2022/4/11 19:30
* @Created by zrc
*/
//实现Filter接口,基于回调的方式,类似ajax请求的success。
public class TestFilter implements Filter {

  //init方法,初始化过滤器,可以在init()方法中完成与构造方法类似的初始化功能,
  //如果初始化代码中要使用到FillerConfig对象,那么这些初始化代码就只能在Filler的init()方法中编写而不能在构造方法中编写
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
      Filter.super.init(filterConfig);
      System.out.println("第一个过滤器成功初始化。。。。。。。。。。。。。");
  }

  //doFilter()方法有多个参数,其中
  //参数request和response为Web服务器或Filter链中的上一个Filter传递过来的请求和响应对象;
  //参数chain代表当前Filter链的对象,
  //只有在当前Filter对象中的doFilter()方法内部需要调用FilterChain对象的doFilter()法才能把请求交付给Filter链中的下一个Filter或者目标程序处理
  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
      HttpServletRequest req = (HttpServletRequest) servletRequest;
      //这里为了使用getHeader方法获取token,转型成HttpServletRequest
      System.out.println("token:"+req.getHeader("token"));
      String token = req.getHeader("token");
      //再判断token是否正确
      if(null==token){
          throw new RuntimeException("token为空");
      }
      //调用doFilter方法,正常返回servletResponse
      filterChain.doFilter(servletRequest, servletResponse);
  }

  //destroy()方法在Web服务器卸载Filter对象之前被调用,该方法用于释放被Filter对象打开的资源,例如关闭数据库和I/O流
  @Override
  public void destroy() {
      Filter.super.destroy();
      System.out.println("过滤器被销毁");
  }
}

实现servlet的Filter接口,并重写他的三个方法,分别是init,doFilter,destroy。

  • init:过滤器初始化时回调,可以在这里做过滤器的初始化操作,例如设置白名单路径列表。
  • doFilter:过滤器初始化后并在请求到达后端且进入到注册过滤器设置的匹配路径时回调。
  • destroy:过滤器销毁时回调。

上图是一个简单实现token校验是否为空,没有进行正确与否的校验,可以引入redis(前面章节有讲到)或者其他的存储,然后进行一个正确性的校验。从request中获取token头,若存在则调用doFilter方法(通过过滤器),否则不作操作(就是不通过过滤器,不会抵达controller)。

2、注册到容器

springboot整合过滤器实战步骤

@Configuration
public class TestFilterConfig {

  @Bean
  public FilterRegistrationBean filterRegistrationBean(){
      //创建一个注册过滤器对象
      FilterRegistrationBean registrationBean = new FilterRegistrationBean();
      //设置自定义过滤器
      registrationBean.setFilter(new TestFilter());
      //设置过滤拦截匹配规则,/*是匹配所有
//        registrationBean.addUrlPatterns("/*");
      //只拦截testController下面的接口
      registrationBean.addUrlPatterns("/testController/*");
      //存在多个过滤器时,设置执行顺序,值越大,执行顺序越靠后
      registrationBean.setOrder(2);
      //返回这个注册过滤器对象
      return registrationBean;
  }

}

将自定义过滤器注册到容器中,通过FilterRegistrationBean的一系列方法设置过滤器的参数,例如需要过滤的路径,过滤器的优先级等等。

3、演示一下效果:

不带token:

springboot整合过滤器实战步骤

springboot整合过滤器实战步骤

带token:

springboot整合过滤器实战步骤

 

三、增加两个过滤器

下面再整一下当存在多个过滤器时,怎么设置哪一个过滤器先拦截,哪一个后执行(优先级)。

跟第二节一样,再整一个自定义过滤器。

springboot整合过滤器实战步骤

package com.example.demo_filter_interceptor.config;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
* @Classname TestFilter
* @Description TODO
* @Date 2022/4/11 19:30
* @Created by zrc
*/
//实现Filter接口,基于回调的方式,类似ajax请求的success。
public class TestFilter2 implements Filter {

  //init方法,初始化过滤器,可以在init()方法中完成与构造方法类似的初始化功能,
  //如果初始化代码中要使用到FillerConfig对象,那么这些初始化代码就只能在Filler的init()方法中编写而不能在构造方法中编写
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
      Filter.super.init(filterConfig);
      System.out.println("第二个过滤器成功初始化。。。。。。。。。。。。。");
  }

  //doFilter()方法有多个参数,其中
  //参数request和response为Web服务器或Filter链中的上一个Filter传递过来的请求和响应对象;
  //参数chain代表当前Filter链的对象,
  //只有在当前Filter对象中的doFilter()方法内部需要调用FilterChain对象的doFilter()法才能把请求交付给Filter链中的下一个Filter或者目标程序处理
  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
      System.out.println("这里是第一顺序的拦截器");
      filterChain.doFilter(servletRequest, servletResponse);
  }

  //destroy()方法在Web服务器卸载Filter对象之前被调用,该方法用于释放被Filter对象打开的资源,例如关闭数据库和I/O流
  @Override
  public void destroy() {
      Filter.super.destroy();
      System.out.println("过滤器被销毁");
  }
}

修改注册过滤器的类。

springboot整合过滤器实战步骤

类似第一个过滤器的注册,再注册一个第二个过滤器即可,可以设置不同的拦截路径,各负责各的逻辑处理,此处只演示一下执行顺序问题,第一个设置Order参数为2,第二个设置为1,越大的越后执行。设置后,用postman测试一下。

springboot整合过滤器实战步骤

调用接口后发现,先进入了第一个过滤器的doFilter方法,再进入的第二个过滤器的doFilter方法,验证order参数是有效的。

到此这篇关于springboot整合过滤器实战的文章就介绍到这了,更多相关springboot整合过滤器内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_56995925/article/details/124108429

延伸 · 阅读

精彩推荐