其实所有的Filter都是一样的原理
大致流程:
- 创建一个自定义Filter, 用于拦截所有异常
- 此Filter正常进行后续Filter调用
- 当调用后续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();
}
}
效果如图所示:
完整demo见github