springboot:如何实现过滤器

在SpringBoot中,可以实现javax.servlet.Filter接口或继承OncePerRequestFilter抽象类来创建过滤器。前者适用于任何Servlet环境,后者确保每个请求只过滤一次。示例包括LogFilter用于记录请求日志,AuthFilter进行身份认证,以及ResponseTimeFilter用于度量请求响应时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Spring Boot中实现过滤器有两种方式,一种是通过实现javax.servlet.Filter接口,另一种是通过实现org.springframework.web.filter.OncePerRequestFilter抽象类。下面分别介绍这两种方式的实现方法。

  1. 实现javax.servlet.Filter接口

首先,创建一个类并实现javax.servlet.Filter接口,并实现其中的doFilter方法。例如,我们创建一个LogFilter类来记录请求日志:

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

public class LogFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String requestURI = httpRequest.getRequestURI();
        System.out.println("请求:" + requestURI);
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // 销毁
    }
}

然后,在Spring Boot应用程序中注册这个过滤器。在Spring Boot中,可以通过创建一个FilterRegistrationBean对象来注册过滤器。例如,我们在MyApplication类中注册LogFilter

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class MyApplication {

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

    @Bean
    public FilterRegistrationBean<LogFilter> logFilter() {
        FilterRegistrationBean<LogFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new LogFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("LogFilter");
        registrationBean.setOrder(1);
        return registrationBean;
    }
}

在上面的代码中,我们创建了一个名为logFilterFilterRegistrationBean对象,并设置了要注册的过滤器LogFilter,过滤的路径addUrlPatterns("/*"),过滤器的名称setName("LogFilter")和执行顺序setOrder(1)

  2. 实现org.springframework.web.filter.OncePerRequestFilter抽象类

另一种实现过滤器的方式是继承org.springframework.web.filter.OncePerRequestFilter抽象类。例如,我们创建一个AuthFilter类来实现身份认证:

import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class AuthFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String authToken = authHeader.substring(7);
            // TODO: 验证token,通过则放行,否则返回错误信息
            filterChain.doFilter(request, response);
        } else {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing or invalid Authorization header.");
        }
    }
}

2.1 OncePerRequestFilter

OncePerRequestFilter是Spring Framework中提供的一个抽象类,用于实现需要在每个请求中执行一次的过滤器。它继承了GenericFilterBean类,并且在doFilter方法中增加了一个判断:如果当前请求已经被过滤器处理过了,则直接放行,不再重复执行。

在Spring Boot中,我们可以通过继承OncePerRequestFilter类来实现自己的过滤器。例如,下面的代码演示了如何实现一个过滤器,用于记录请求的响应时间:

import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ResponseTimeFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        long startTime = System.currentTimeMillis();
        filterChain.doFilter(request, response);
        long endTime = System.currentTimeMillis();
        System.out.println("请求 " + request.getRequestURI() + " 的响应时间为 " + (endTime - startTime) + " 毫秒");
    }
}

在上面的代码中,我们继承了OncePerRequestFilter类,并实现了doFilterInternal方法,在方法中记录了请求的响应时间。需要注意的是,doFilterInternal方法中必须调用filterChain.doFilter方法来继续执行后续的过滤器或请求处理程序。

要在Spring Boot中注册这个过滤器,可以在@Configuration类中使用FilterRegistrationBean对象,像这样:

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<ResponseTimeFilter> responseTimeFilter() {
        FilterRegistrationBean<ResponseTimeFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new ResponseTimeFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("ResponseTimeFilter");
        registrationBean.setOrder(1);
        return registrationBean;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值