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

Spring Boot Filter统一处理异常,可以通过自定义一个异常处理器类,并在 Filter 中进行调用。 首先,创建一个自定义的异常处理器类,例如:`CustomExceptionHandler.java`,实现 `ExceptionHandler` 接口,该接口有一个方法 `handleException(Throwable ex)`,用于处理异常。在这个方法中,我们可以对不同类型的异常进行不同的处理,比如返回不同的错误信息等。示例代码如下: ```java public class CustomExceptionHandler implements ExceptionHandler { @Override public void handleException(Throwable ex) { if (ex instanceof ServletException) { // 处理 ServletException 异常 } else if (ex instanceof IOException) { // 处理 IOException 异常 } else if (ex instanceof RuntimeException) { // 处理 RuntimeException 异常 } // ... } } ``` 然后,在 Filter 中进行调用。在 Filter 的 `doFilter()` 方法中,捕获异常,并将异常传递给自定义异常处理器进行处理。示例代码如下: ```java public class CustomFilter implements Filter { @Override public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { // 执行过滤操作 chain.doFilter(request, response); } catch (Throwable ex) { // 异常处理 CustomExceptionHandler handler = new CustomExceptionHandler(); handler.handleException(ex); } } // ... } ``` 最后,将自定义 Filter 注册到 Spring Boot 中。可以通过 `@WebFilter` 注解或者在 Spring Boot 的配置类中进行配置。示例代码如下: ```java @Configuration public class AppConfig { @Bean public FilterRegistrationBean<CustomFilter> customFilter() { FilterRegistrationBean<CustomFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(new CustomFilter()); registration.addUrlPatterns("/*"); return registration; } } ``` 这样,当 Filter 中发生异常时,就会调用自定义异常处理器进行异常处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值