所有分类
  • 所有分类
  • 未分类

SpringBoot-过滤器(Filter)的用法

简介 

说明

本文用示例介绍SpringBoot(SpringMVC)中的过滤器的用法。

Filter可以有多个。一个filter执行完之后会执行另外一个。

注册过滤器的方法

注册方式有:(本质都是一样的,都是去FilterRegistrationBean注册自定义Filter ):

  1. 注册Bean,实现Filter接口。(可用@Order或者实现Ordered接口指定顺序)
  2. 使用FilterRegistrationBean注册Filter。(可用setOrder指定顺序)
  3. 使用原生servlet注解(@WebFilter)定义Filter。(缺点:无法指定过滤器顺序)

过滤器的使用场景

  1. 控制用户访问权限
  2. 记录日志
  3. 图像转换
  4. 数据压缩
  5. 加密
  6. Token校验
  7. 媒体类型过滤

注册方式实例

注册方式1:注册Bean

package com.knife.example.filter;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

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

@Component
@Order(1)
public class MyFilter1 implements Filter {
    @Override
    public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilter1.init");
        System.out.println("MyFilter1 过滤器名:" + filterConfig.getFilterName());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        // do something 处理request 或response
        System.out.println("MyFilter1.doFilter");
        if (servletRequest instanceof HttpServletRequest) {
            System.out.println("MyFilter1 URL:" + ((HttpServletRequest) servletRequest).getRequestURL());
        }
        // 调用filter链中的下一个filter
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("MyFilter1.destroy");
    }
}

注册方式2:FilterRegistrationBean

定义Filter 

package com.knife.example.filter;

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

public class MyFilter implements Filter {
    @Override
    public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilter.init");
        System.out.println("  过滤器名:" + filterConfig.getFilterName());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // do something 处理request 或response
        System.out.println("MyFilter.doFilter");

        if (servletRequest instanceof HttpServletRequest) {
            System.out.println("  URL:" + ((HttpServletRequest)servletRequest).getRequestURL());
        }

        // 调用filter链中的下一个filter
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("MyFilter.destroy");
    }
}

注册自定义Filter 

package com.knife.example.filter;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean registrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }
}

注册方式3:@WebFilter

此法的缺点:无法指定过滤器顺序。

package com.knife.example.filter;

import org.springframework.stereotype.Component;

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

@Component
// 定义filterName 和过滤的url
@WebFilter(filterName = "myFilter" ,urlPatterns = "/*")
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilter.init");
        System.out.println("  过滤器名:" + filterConfig.getFilterName());
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // do something 处理request 或response
        System.out.println("MyFilter.doFilter");

        if (servletRequest instanceof HttpServletRequest) {
            System.out.println("  URL:" + ((HttpServletRequest)servletRequest).getRequestURL());
        }

        // 调用filter链中的下一个filter
        filterChain.doFilter(servletRequest,servletResponse);
    }
    @Override
    public void destroy() {
        System.out.println("MyFilter.destroy");
    }
}

实例:多过滤器

代码

过滤器1

package com.knife.example.filter;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

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

@Component
@Order(1)
public class MyFilter1 implements Filter {
    @Override
    public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilter1.init");
        System.out.println("MyFilter1 过滤器名:" + filterConfig.getFilterName());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        // do something 处理request 或response
        System.out.println("MyFilter1.doFilter");
        if (servletRequest instanceof HttpServletRequest) {
            System.out.println("MyFilter1 URL:" + ((HttpServletRequest) servletRequest).getRequestURL());
        }
        // 调用filter链中的下一个filter
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("MyFilter1.destroy");
    }
}

过滤器2

package com.knife.example.filter;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

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

@Component
@Order(2)
public class MyFilter2 implements Filter {
    @Override
    public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilter2.init");
        System.out.println("MyFilter2 过滤器名:" + filterConfig.getFilterName());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // do something 处理request 或response
        System.out.println("MyFilter2.doFilter");
        if (servletRequest instanceof HttpServletRequest) {
            System.out.println("MyFilter2 URL:" + ((HttpServletRequest) servletRequest).getRequestURL());
        }
        // 调用filter链中的下一个filter
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("MyFilter2.destroy");
    }
}

Controller

package com.knife.example.controller;


import com.knife.example.bo.UserBO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@Api(tags = "测试")
@RequestMapping("test")
@RestController
public class TestController {

    @ApiOperation("测试1")
    @GetMapping("test1")
    public String test1(UserBO userBO) {
        System.out.println("TestController.test1");

        return "success";
    }
}

实体类 

package com.knife.example.bo;

import lombok.Data;

@Data
public class UserBO {
    private Integer id;

    private String name;

    private Integer age;
}

测试

测试1:启动、访问接口、关闭

启动SpringBoot

2025-12-09 19:29:45.505  INFO 3360 --- [           main] com.knife.example.DemoApplication        : Starting DemoApplication using Java 1.8.0_202 on DESKTOP-RLBS3B1 with PID 3360 (E:\work\idea_proj\Demo_Java\Demo_Filter_SpringBoot\target\classes started by aaa in E:\work\idea_proj\Demo_Java\Demo_Filter_SpringBoot)
2025-12-09 19:29:45.509  INFO 3360 --- [           main] com.knife.example.DemoApplication        : No active profile set, falling back to default profiles: default
2025-12-09 19:29:46.719  INFO 3360 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2025-12-09 19:29:46.727  INFO 3360 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2025-12-09 19:29:46.728  INFO 3360 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.55]
2025-12-09 19:29:46.828  INFO 3360 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2025-12-09 19:29:46.828  INFO 3360 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1261 ms
MyFilter2.init
MyFilter2 过滤器名:myFilter2
MyFilter1.init
MyFilter1 过滤器名:myFilter1
2025-12-09 19:29:47.477  INFO 3360 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2025-12-09 19:29:47.778  INFO 3360 --- [           main] com.knife.example.DemoApplication        : Started DemoApplication in 2.812 seconds (JVM running for 3.912)

浏览器访问:http://localhost:8080/test/test1?age=12&id=2&name=Tony

后端结果

MyFilter1.doFilter
MyFilter1 URL:http://localhost:8080/test/test1
MyFilter2.doFilter
MyFilter2 URL:http://localhost:8080/test/test1
TestController.test1

关闭SpringBoot 

MyFilter2.destroy
MyFilter1.destroy

测试2:配置类setOrder的值调换顺序

过滤器

过滤器1

package com.knife.example.filter;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

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

@Component
@Order(2)
public class MyFilter1 implements Filter {
    @Override
    public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilter1.init");
        System.out.println("MyFilter1 过滤器名:" + filterConfig.getFilterName());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        // do something 处理request 或response
        System.out.println("MyFilter1.doFilter");
        if (servletRequest instanceof HttpServletRequest) {
            System.out.println("MyFilter1 URL:" + ((HttpServletRequest) servletRequest).getRequestURL());
        }
        // 调用filter链中的下一个filter
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("MyFilter1.destroy");
    }
}

过滤器2

package com.knife.example.filter;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

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

@Component
@Order(1)
public class MyFilter2 implements Filter {
    @Override
    public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilter2.init");
        System.out.println("MyFilter2 过滤器名:" + filterConfig.getFilterName());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // do something 处理request 或response
        System.out.println("MyFilter2.doFilter");
        if (servletRequest instanceof HttpServletRequest) {
            System.out.println("MyFilter2 URL:" + ((HttpServletRequest) servletRequest).getRequestURL());
        }
        // 调用filter链中的下一个filter
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("MyFilter2.destroy");
    }
}

启动SpringBoot

2025-12-09 09:33:24.996  INFO 2224 --- [           main] com.knife.example.DemoApplication        : Starting DemoApplication using Java 1.8.0_202 on DESKTOP-RLBS3B1 with PID 2224 (E:\work\idea_proj\Demo_Java\Demo_Filter_SpringBoot\target\classes started by aaa in E:\work\idea_proj\Demo_Java\Demo_Filter_SpringBoot)
2025-12-09 09:33:24.999  INFO 2224 --- [           main] com.knife.example.DemoApplication        : No active profile set, falling back to default profiles: default
2025-12-09 09:33:25.752  INFO 2224 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2025-12-09 09:33:25.757  INFO 2224 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2025-12-09 09:33:25.757  INFO 2224 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.55]
2025-12-09 09:33:25.822  INFO 2224 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2025-12-09 09:33:25.822  INFO 2224 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 789 ms
MyFilter2.init
MyFilter2 过滤器名:myFilter2
MyFilter1.init
MyFilter1 过滤器名:myFilter1
2025-12-09 09:33:26.241  INFO 2224 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2025-12-09 09:33:26.463  INFO 2224 --- [           main] com.knife.example.DemoApplication        : Started DemoApplication in 1.836 seconds (JVM running for 2.651)

浏览器访问:http://localhost:8080/test/test1?age=12&id=2&name=Tony

后端结果(可见,按照指定的顺序执行了)

MyFilter2.doFilter
MyFilter2 URL:http://localhost:8080/test/test1
MyFilter1.doFilter
MyFilter1 URL:http://localhost:8080/test/test1
TestController.test1

关闭SpringBoot

MyFilter2.destroy
MyFilter1.destroy

实例:拦截请求

如果想要拦截请求,直接报错,方法是:

  • 拦截:直接return,不调用filterChain.doFilter(servletRequest,servletResponse);即可
  • 报错:将报错直接写到HttpServletResponse里。

0

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录