Spring Boot中的自定义过滤器
今天我们来聊聊Spring Boot中的自定义过滤器。过滤器是Java Web开发中处理HTTP请求和响应的重要组件。Spring Boot提供了简单且强大的过滤器配置机制,使得创建和管理自定义过滤器变得非常方便。
一、过滤器概述
过滤器(Filter)是一种用于预处理请求和后处理响应的组件。它可以拦截请求和响应,对其进行修改或处理。常见的用途包括日志记录、身份验证、安全检查、数据压缩等。
二、创建自定义过滤器
在Spring Boot中创建自定义过滤器非常简单。我们需要实现javax.servlet.Filter
接口,并重写其中的doFilter
方法。接下来,我们将创建一个示例过滤器,记录请求的处理时间。
1. 创建过滤器类
首先,我们创建一个过滤器类,命名为RequestLoggingFilter
:
package cn.juwatech.filter; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import java.io.IOException; public class RequestLoggingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化过滤器配置 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { long startTime = System.currentTimeMillis(); chain.doFilter(request, response); long endTime = System.currentTimeMillis(); System.out.println("Request processed in " + (endTime - startTime) + " ms"); } @Override public void destroy() { // 销毁过滤器 } }
2. 注册过滤器
接下来,我们需要将这个过滤器注册到Spring Boot应用中。我们可以通过配置类或注解来完成。
通过配置类注册过滤器:
package cn.juwatech.config; import cn.juwatech.filter.RequestLoggingFilter; 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<RequestLoggingFilter> loggingFilter() { FilterRegistrationBean<RequestLoggingFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new RequestLoggingFilter()); registrationBean.addUrlPatterns("/*"); return registrationBean; } }
通过注解注册过滤器:
如果使用Spring Boot 2.0及以上版本,可以直接在过滤器类上使用@Component
注解进行注册:
package cn.juwatech.filter; import org.springframework.stereotype.Component; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import java.io.IOException; @Component public class RequestLoggingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化过滤器配置 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { long startTime = System.currentTimeMillis(); chain.doFilter(request, response); long endTime = System.currentTimeMillis(); System.out.println("Request processed in " + (endTime - startTime) + " ms"); } @Override public void destroy() { // 销毁过滤器 }
三、过滤器的应用场景
- 日志记录
日志记录是过滤器最常见的应用场景之一。通过自定义过滤器,可以记录每个请求的详细信息,包括处理时间、请求参数、响应状态等。
package cn.juwatech.filter; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import java.io.IOException; public class LoggingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("Request received at " + System.currentTimeMillis()); chain.doFilter(request, response); System.out.println("Response sent at " + System.currentTimeMillis()); } @Override public void destroy() { // 销毁 } }
- 身份验证
过滤器还可以用于身份验证。在处理请求之前,可以检查请求头或Cookie中的身份信息,决定是否允许请求通过。
package cn.juwatech.filter; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import java.io.IOException; public class AuthenticationFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 简单示例,实际应用中应使用更安全的方式 String token = request.getParameter("token"); if ("valid-token".equals(token)) { chain.doFilter(request, response); } else { response.getWriter().write("Authentication failed"); } } @Override public void destroy() { // 销毁 } }
- 数据压缩
过滤器还可以用于响应数据的压缩。通过在过滤器中对响应数据进行压缩,可以减少传输的数据量,提高传输效率。
package cn.juwatech.filter; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.zip.GZIPOutputStream; public class CompressionFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse httpServletResponse = (HttpServletResponse) response; GZIPResponseWrapper gzipResponseWrapper = new GZIPResponseWrapper(httpServletResponse); chain.doFilter(request, gzipResponseWrapper); gzipResponseWrapper.finish(); } @Override public void destroy() { // 销毁 } } class GZIPResponseWrapper extends HttpServletResponseWrapper { private GZIPOutputStream gzipOutputStream = null; private ServletOutputStream servletOutputStream = null; public GZIPResponseWrapper(HttpServletResponse response) throws IOException { super(response); this.servletOutputStream = response.getOutputStream(); this.gzipOutputStream = new GZIPOutputStream(servletOutputStream); } @Override public ServletOutputStream getOutputStream() throws IOException { return new ServletOutputStream() { @Override public boolean isReady() { return servletOutputStream.isReady(); } @Override public void setWriteListener(WriteListener writeListener) { servletOutputStream.setWriteListener(writeListener); } @Override public void write(int b) throws IOException { gzipOutputStream.write(b); } }; } public void finish() throws IOException { gzipOutputStream.finish(); } }
四、总结
本文介绍了Spring Boot中的自定义过滤器,包括过滤器的基本概念、创建和注册方法以及常见的应用场景。通过自定义过滤器,我们可以在请求处理的各个阶段进行灵活的操作,从而实现日志记录、身份验证和数据压缩等功能。希望本文能够帮助你更好地理解和使用Spring Boot中的过滤器。