我们一般用 @[Rest]ControllerAdvice 来做 Controller 的全局错误处理,比如在项目中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
@Slf4j @RestControllerAdvice public class ExceptionAdviceHandler {
@ExceptionHandler(value = HttpRequestMethodNotSupportedException.class) @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) public ResultWrapper<?> methodNotAllowed() { return ResultWrapper.error(ResponseEnum.ERROR_REQUEST_METHOD); }
@ExceptionHandler(NoHandlerFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public ResultWrapper<?> handleError404() { return ResultWrapper.error(ResponseEnum.NOT_FOUND); }
}
|
但是有时候,在 Filter 或者 Interceptor 中,也会有错误抛出,这些错误就不能被捕获了。这时候可以用自定义的 Filter 去 try-catch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Component @WebFilter(urlPatterns = "/**") @Order(Ordered.HIGHEST_PRECEDENCE) public class NotLoginFilter extends OncePerRequestFilter {
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { try { filterChain.doFilter(request, response); } catch (NestedServletException e) { if (e.getCause() instanceof NotLoginException) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); response.getWriter().write(JsonUtils.objectToJson(ResultWrapper.error(ResponseEnum.INVALID_TOKEN))); } else { throw e; } } } }
|
对于 404 错误的,默认是系统返回结果:
1 2 3 4 5 6 7
| { "timestamp": "2021-10-14 15:01:50", "status": 404, "error": "Not Found", "message": "No message available", "path": "/unknown" }
|
现在想要统一返回值,需要配置 application.properties。并且不使用 @EnableWebMvc(stackoverflow),与 ResponseBodyAdvice 配置有冲突?TODO:
1 2 3
| spring.mvc.throw-exception-if-no-handler-found=true server.error.whitelabel.enabled=false spring.resources.add-mappings=false
|
并添加 ExceptionHandler
1 2 3 4 5
| @ExceptionHandler(NoHandlerFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public ResultWrapper<?> handleError404() { return ResultWrapper.error(ResponseEnum.NOT_FOUND); }
|