简介
说明
本文用示例介绍SpringBoot(SpringMVC)中的过滤器的用法。
Filter可以有多个。一个filter执行完之后会执行另外一个。
注册过滤器的方法
注册方式有:(本质都是一样的,都是去FilterRegistrationBean注册自定义Filter ):
- 注册Bean,实现Filter接口。(可用@Order或者实现Ordered接口指定顺序)
- 使用FilterRegistrationBean注册Filter。(可用setOrder指定顺序)
- 使用原生servlet注解(@WebFilter)定义Filter。(缺点:无法指定过滤器顺序)
过滤器的使用场景
- 控制用户访问权限
- 记录日志
- 图像转换
- 数据压缩
- 加密
- Token校验
- 媒体类型过滤
注册方式实例
注册方式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里。

请先 !