springboot OncePerRequestFilter过滤器

前言

之前的文章SpringBoot拦截器HandlerInterceptor实现讲了 HandlerInterceptor 拦截器。
文本讲解 OncePerRequestFilter 过滤器的使用。

一、 HandlerInterceptor拦截器与OncePerRequestFilter过滤器的区别

1.应用场景:

  • HandlerInterceptor 主要用于 Spring MVC 的请求处理流程中,适合进行日志记录、参数校验等操作。
  • OncePerRequestFilter 主要用于 Spring Security 的过滤器链中,适合进行安全性相关的操作,如认证、授权等。

2.生命周期:

  • HandlerInterceptor 在控制器方法执行前后执行,主要用于请求处理流程的控制。
  • OncePerRequestFilter 在每次请求时执行一次,主要用于安全性相关的过滤任务。

3.实现方式:

  • HandlerInterceptor 通过实现 HandlerInterceptor 接口并注册到 WebMvcConfigurer 中。
  • OncePerRequestFilter 通过继承 OncePerRequestFilter 类并实现 doFilterInternal 方法,并在 Spring Security 配置中注册。

选择建议
如果你需要在请求处理流程中进行一些通用的操作,如日志记录、参数校验等,可以选择使用 HandlerInterceptor。
如果你需要进行安全性相关的过滤任务,如认证、授权等,可以选择使用 OncePerRequestFilter。
根据实际需求选择合适的拦截机制,可以使代码更加清晰和易于维护。

二、OncePerRequestFilter过滤器使用示例

下面的过滤器继承自 OncePerRequestFilter 然后使用 @Component 注入到容器,当每一个请求来的时候都会执行 doFilterInternal 方法,从每一个请求的HTTP请求头中获取Authorization的值,也就是的token,并调用checkToken方法进行校验。如果token校验失败,则不继续执行过滤链,直接返回错误信息的JSON字符串。


import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
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;

@Component
public class AuthFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        //从头中获取token并校验
        String token = request.getHeader("Authorization");
        if (!checkToken(token, request, response)) {
            return;
        }
        filterChain.doFilter(request, response);
    }

    private boolean checkToken(String token, HttpServletRequest request, HttpServletResponse response) throws IOException {
        //检查token是否有效
        if (!checkToken(token)) {
            // token校验失败
            writeErrorMessage(request, response);
            return false;
        }
        return true;
    }

    //检查token是否有效
    private boolean checkToken(String token) {
        //todo 在这里验证token的有效性
        //......
        return true;
    }


    public void writeErrorMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String jsonString = "{\n" +
                "    \"code\": \"-1\",\n" +
                "    \"msg\": \"token无效\",\n" +
                "    \"detail\": \"\"\n" +
                "}";
        String origin = request.getHeader("Origin");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Origin", origin != null && origin.trim().length() > 0 ? origin : "*");
        response.setHeader("Access-Control-Allow-Methods", "*");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setStatus(HttpStatus.OK.value());
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json");
        response.getWriter().write(jsonString);
        response.getWriter().flush();
    }
}


参考:
Spring 过滤器:OncePerRequestFilter 应用详解
OncePerRequestFilter详解

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值