自定义异常类(配合结果类)
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
|
@Getter @AllArgsConstructor public class GlobalException extends RuntimeException {
private Integer code = FAILED.getCode();
private final String message;
public GlobalException(String message) { this.message = message; }
public GlobalException(ResultCode resultCode) { this.code = resultCode.getCode(); this.message = resultCode.getMessage(); }
}
|
这里需要注意的是,自定义异常需要继承RuntimeException(运行时异常)。
定义全局异常处理
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
@Slf4j @RestControllerAdvice public class ControllerAdviceHandler {
@ExceptionHandler(value = GlobalException.class) public <T> Result<T> globalExceptionHandler(GlobalException e, HttpServletRequest request) { log.error(">> global exception: {}, {}, {}", request.getRequestURI(), e.getCode(), e.getMessage()); String errMessage = e.getMessage(); if (StringUtils.isBlank(errMessage)) { errMessage = "服务器繁忙"; } return Result.failure(e.getCode(), errMessage); }
@ExceptionHandler(value = Exception.class) public <T> Result<T> defaultErrorHandler(Exception e, HttpServletRequest request) { log.error(">> 服务器内部错误 " + request.getRequestURI(), e.getMessage()); return Result.failure(500, "服务器繁忙"); }
}
|
@RestControllerAdvice注解其实是@ControllerAdvice和@ResponseBody的合并。
@ControllerAdvice通常配合@ExceptionHandler来捕抓异常信息。
@ControllerAdvice可以捕抓到系统抛出的异常,然后使用@ExceptionHandler匹配具体处理异常信息。
特殊的异常处理
有些异常是不会走全局异常处理的,即不会被捕捉到,比如在过滤器中的异常,这种异常是没有经过controller
的,所以发生了异常,也不会通过被上述的方式捕捉到。
以下是一个捕捉Token过滤器异常的例子。
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
@Slf4j public class TokenAuthenticationFilter extends BasicAuthenticationFilter {
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) { try { ..... } catch (AlgorithmMismatchException | SignatureVerificationException | TokenExpiredException | MissingClaimException | IncorrectClaimException e) { errorHandler(request, response, e); } }
private void errorHandler(HttpServletRequest request, HttpServletResponse response, Exception e) { if (e instanceof AlgorithmMismatchException) { resolver.resolveException(request, response, null, new AlgorithmMismatchException(e.getMessage())); return; } if (e instanceof TokenExpiredException) { resolver.resolveException(request, response, null, new TokenExpiredException( e.getMessage(), ((TokenExpiredException) e).getExpiredOn()) ); return; } if (e instanceof MissingClaimException) { resolver.resolveException(request, response, null, new MissingClaimException( ((MissingClaimException) e).getClaimName()) ); return; } if (e instanceof IncorrectClaimException) { resolver.resolveException(request, response, null, new IncorrectClaimException( e.getMessage(), ((IncorrectClaimException) e).getClaimName(), ((IncorrectClaimException) e).getClaimValue()) ); return; } if (e instanceof JWTVerificationException) { resolver.resolveException(request, response, null, new JWTVerificationException( e.getMessage(), e.getCause()) ); } }
}
|