其实所有的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