SpringBoot SaToken Filter如用使用ControllerAdvice统一异常拦截

其实所有的Filter都是一样的原理

大致流程:

  1. 创建一个自定义Filter, 用于拦截所有异常
  2. 此Filter正常进行后续Filter调用
  3. 当调用后续Filter时, 如果发生异常, 则委托给HandlerExceptionResolver进行后续处理即可

以sa-token的SaServletFilter为例

首先注册SaToken的过滤器

package kim.nzxy.demo.config;

import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SaTokenConfig {
    /**
     * 注册 [Sa-Token全局过滤器]
     */
    @Bean
    public SaServletFilter getSaServletFilter() {
        return new SaServletFilter()
                .addInclude("/**").addExclude("/favicon.ico", "/hello.html")
                .setAuth(obj -> StpUtil.checkLogin());
    }
}

其次, 自定义一个自己的过滤器, 优先级设为最高:

package kim.nzxy.demo.filter;

import jakarta.servlet.FilterChain;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.HandlerExceptionResolver;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ExceptionHandlerFilter extends OncePerRequestFilter {
    private HandlerExceptionResolver resolver;

    @Autowired
    public void setResolver(@Qualifier("handlerExceptionResolver") HandlerExceptionResolver resolver) {
        this.resolver = resolver;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
        try {
            filterChain.doFilter(request, response);
        } catch (Exception e) {
            resolver.resolveException(request, response, null, e);
        }
    }
}

最后, 自定义一个自己的异常拦截器, 这里就直接返回文字格式的异常Message了:

package kim.nzxy.demo.ex;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @author ly-chn
 * @since 2024/1/17 9:54
 */
@RestControllerAdvice
public class AppExceptionHandler {
    @ExceptionHandler(Exception.class)
    public String handler(Exception e) {
        return "Some error happened: " + e.getMessage();
    }
}

效果如图所示:

image-20240117114112467

完整demo见github