Spring-Boot 过滤器

本文介绍了Springboot中过滤器Filter的使用,包括定义WebFilter、开启过滤器支持,并通过示例展示了过滤器的执行流程。同时,对比了过滤器与拦截器的区别,强调了过滤器在所有请求处理前执行,拦截器只能拦截控制器接口请求,且拦截器可以访问更多上下文信息。最后,提供了自定义配置类注册过滤器的方式。
摘要由CSDN通过智能技术生成

过滤器Filter

概述

过滤器是Web开发中很实用的意向技术,程序员可以通过过滤器对web服务资源,

  • 静态资源 比如:静态HTML、静态图片,js或者css等,
  • 动态资源比如:JSP,Servlet等进行拦截器

从而实现一些特殊的需求,比如:URL的访问权限,过滤的敏感词汇,压缩响应信息等,

完整的执行过程

在这里插入图片描述

Springboot如何定义Filter呢(默认机制)

1:定义一个过滤器WebFilter

package com.kuangstudy.config.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import java.io.IOException;

@WebFilter(urlPatterns = "/api/*", filterName = "WebTestFilter", initParams = {
        @WebInitParam(name = "encoding", value = "UTF-8")
})
@Order(1)
@Slf4j
public class WebTestFilter implements Filter {


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化 获取拦截器配置的参数
        String encoding = filterConfig.getInitParameter("encoding");
        log.info("encoding:{}",encoding);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("1------>doFilter进来了....");
        // 下面的代码很关键,如果没有就代表请求进入过滤器,就终止了,就不会返回资源给用户
        filterChain.doFilter(servletRequest, servletResponse);// 1: 如果还有过滤器,会进入到下一个过滤器  2:如果没有过滤器。直接去访问servlet /jsp/ 静态资源
    }

    @Override
    public void destroy() {
        log.info("过滤执行完毕了.....");
    }
}

2:开启springboot对filter和监听器的支持

增加@ServletComponentScan开关

package com.kuangstudy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan
public class SpringbootInterceptorApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootInterceptorApplication.class, args);
    }

}

3:请求一个springmvc的路由资源

http://localhost:8987/api/index

查看结果得出结论如下:

2021-12-27 21:31:14.269  INFO 20460 --- [nio-8987-exec-1] c.k.config.filter.WebTestFilter          : 1------>doFilter进来了....
2021-12-27 21:31:27.664  INFO 20460 --- [nio-8987-exec-1] c.k.config.handler.LoginInterceptor      : 1---LoginInterceptor--preHandle----->
2021-12-27 21:31:27.664  INFO 20460 --- [nio-8987-exec-1] c.k.c.handler.PermissionInterceptor      : 1---PermissionInterceptor--preHandle----->
2021-12-27 21:31:27.679  INFO 20460 --- [nio-8987-exec-1] com.kuangstudy.web.HelloWorldController  : 2------>index
2021-12-27 21:31:27.687  INFO 20460 --- [nio-8987-exec-1] c.k.c.handler.PermissionInterceptor      : 3---PermissionInterceptor--postHandle----->
2021-12-27 21:31:27.687  INFO 20460 --- [nio-8987-exec-1] c.k.config.handler.LoginInterceptor      : 3--LoginInterceptor---postHandle----->
2021-12-27 21:31:27.741  INFO 20460 --- [nio-8987-exec-1] c.k.c.handler.PermissionInterceptor      : 4---PermissionInterceptor --afterCompletion----->
2021-12-27 21:31:27.741  INFO 20460 --- [nio-8987-exec-1] c.k.config.handler.LoginInterceptor      : 4---LoginInterceptor--afterCompletion----->

4:总结

过滤器Filter先于拦截器Intetercptor执行。

03、自定义配置类 + 注册过滤器

自定义配置类配置过滤器就是定义一个:过滤器实现Filter接口,然后此过滤器的以@Bean的形式注册到配置类中。以及它他规则全部在@Bean定义的过滤器的方法中进行完成。

package com.kuangstudy.config.filter;

import org.apache.catalina.filters.RequestFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;

@Configuration
public class RequestTestFilterConfiguration {

    @Bean
    public FilterRegistrationBean filterRequeset() {
        // 1: 定义一个过滤器的注册bean
        FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>();
        // 2: 初始化自定义filter
        RequestTestFilter requestTestFilter = new RequestTestFilter();
        // 注册过滤器到ioc容器中
        filterFilterRegistrationBean.setFilter(requestTestFilter);
        // 设置过滤器规则
        filterFilterRegistrationBean.addUrlPatterns("/api/**");
        // 设置过滤器名字
        filterFilterRegistrationBean.setName("RequestTestFilter");
        // 设置参数
        filterFilterRegistrationBean.addInitParameter("encoding", "GBK");
        // 设置执行顺序
        filterFilterRegistrationBean.setOrder(3);
        // 返回
        return filterFilterRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean filterRequeset2() {
        // 1: 定义一个过滤器的注册bean
        FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>();
        // 2: 初始化自定义filter
        RequestTestFilter2 requestTestFilter2 = new RequestTestFilter2();
        // 注册过滤器到ioc容器中
        filterFilterRegistrationBean.setFilter(requestTestFilter2);
        // 设置过滤器规则
        filterFilterRegistrationBean.addUrlPatterns("/api/**");
        // 设置过滤器名字
        filterFilterRegistrationBean.setName("RequestTestFilter2");
        // 设置参数
        filterFilterRegistrationBean.addInitParameter("encoding", "GBK");
        // 设置执行顺序
        filterFilterRegistrationBean.setOrder(2);
        // 返回
        return filterFilterRegistrationBean;
    }

}

过滤器和拦截器的区别

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

  • 过滤器(Filter)是容器的基于函数回调的执行。拦截器:是基于java的反射机制的,

    filter是由web容器来调用,拦截器是springmvc的ioc容器来调用。

        Filter的执行是一种基于函数回调执行,
        代表就是:所以过滤器的都由容器来统一执行。
        web/servlet 容器。tomcat在启动的时候---初始化servlet,
        Filter 在初始化Filter时候就根据接口找到所有的自定义的filter, 
        将其加载内存中,然后请求进入之间把加载号的filter一个个执行触发。
    
  • 过滤器(Filter) 几乎可以顾虑所以的请求(不论静态(js/css/img/html)和动态(jsp/servlet))。而拦截器只能拦截controller中定义的接口路由请求。拦截器不处理静态资源

    番外:那么springmvc处理静态资源机制是什么:过滤器 拦截器所以 /static/*

  • 拦截器可以访问controller中方法和上下文,以及值栈信息,而过滤器不能获取。

  • 在controller的生命周期中,

    • 过滤器只能在容器初始化的时候调用一次init方法,
    • 拦截器必须要在请求的时候才会执行和触发。
  • 拦截器可以获取ioc各种的bean,根据需求进行业务处理,但是过滤不支持这种方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值