Springboot 过滤器

过滤器是什么?

它是基于Servlet 技术实现的, 简单的来说,过滤器就是起到过滤的作用,在web项目开发中帮我们过滤一些指定的 url做一些特殊的处理。

过滤器主要做什么?

过滤掉一些不需要的东西,例如一些错误的请求。
也可以修改请求和相应的内容。
也可以拿来过滤未登录用户。

过滤器的代码实现

过滤器(filter)有三个方法,其中初始化(init)和摧毁(destroy)方法一般不会用到,主要用到的是doFilter这个方法。

怎么过滤呢?

如果过滤通过,则在doFilter执行filterChain.doFilter(request,response);

那么在springBoot中如何使用过滤器呢?

自定义Filter有两种实现方式,第一种是使用@WebFilter,第二种是使用 FilterRegistrationBean

@WebFilter 实现

@WebFilter 用于将一个类声明为过滤器,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为过滤器。


image.png
  1. 创建一个MyFilter.java实现Filter接口
@WebFilter(urlPatterns = "/api/*",filterName = "myFilter")
@Order(1)//指定过滤器的执行顺序,值越大越靠后执行
public class MyFilter implements Filter {
  @Override
public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("初始化过滤器");
}
@Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 
FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request= (HttpServletRequest) servletRequest;
        String uri=request.getRequestURI();
        String method=request.getMethod();
        System.out.println(uri+" "+method+"哈哈我进入了 MyFilter 过滤器了");
        filterChain.doFilter(servletRequest,servletResponse);
     
   }
}
  1. 启动类加上 @ServletComponentScan 注解
  2. 创建一个 FilterController 接口
@RestController
@RequestMapping("/api")
public class HelloController {
    @GetMapping("/user/filter")
    public String hello(){
        return "哈哈我通过了过滤器";
   }
}
  1. 测试


    image.png
FilterRegistrationBean 实现
  1. 创建 FilterConfig
@Configuration
public class FilterConfig {
   @Bean
    public MyFilter myFilter(){
        return new MyFilter();
   }
    @Bean
    public FilterRegistrationBean getFilterRegistrationBean(MyFilter myFilter){
        FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean();
        /**
         * 设置过滤器
         */
        filterRegistrationBean.setFilter(MyFilter());
        /**
         * 拦截路径
         */
        filterRegistrationBean.addUrlPatterns("/api/*");
        /**
         * 设置名称
         */
        filterRegistrationBean.setName("myFilter");
        /**
         * 设置访问优先级 值越小越高
         */
        filterRegistrationBean.setOrder(1);
        return filterRegistrationBean;
   }
}
  1. 修改 MyFilter.java
//@WebFilter(urlPatterns ={"/api/*"},filterName = "myFilter")
  1. 修改启动类
//@ServletComponentScan
  1. 测试


    image.png

过滤校验用户是否登录实战

  1. 修改 application.properties 加入开发接口通配地址
#凡是请求地址层级带有 open 都放行
open.url=/**/open/**
  1. 修改 MyFilter
//@WebFilter(urlPatterns ={"/*"},filterName = "myFilter")
public class MyFilter implements Filter {
    @Value("${open.url}")
    private String openUrl;
    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("初始化 myFilter 过滤器");
   }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 
FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String requestUrl = request.getRequestURI();
        System.out.println("过滤器MyFilter拦截了请求为" + requestUrl);
        //首先校验是否是开放 api
        //是直接放行,否再校验token
        PathMatcher matcher = new AntPathMatcher();
        if(matcher.match(openUrl,requestUrl)){
            filterChain.doFilter(servletRequest,servletResponse);
        }else {
            String token=request.getHeader("token");
            if(StringUtils.isEmpty(token)){
                servletRequest.getRequestDispatcher("/api/open/unLogin").forward(servletRequest,
                        servletResponse);
           }else {
                filterChain.doFilter(servletRequest,servletResponse);
           }
       }
   }
}
  1. 新增 未登录接口、首页接口
@GetMapping("/open/home/info")
    public Map<String,String> getHome(){
        Map<String,String> map=new HashMap<>();
        map.put("游客","欢迎访问首页");
        return map;
   }
    
    @GetMapping("/open/unLogin")
    public String getUnauthorized(){
        return "登录失效,请重新登录";
   }
  1. 测试
  2. 首先访问 开放接口


    image.png
  3. 访问需权鉴接口


    image.png
  4. 带上 token


    image.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。