@ExceptionHandler注解我们一般是用来自定义异常的。 可以认为它是一个异常拦截器(处理器)。
@Slf4j @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler({HttpMessageNotReadableException.class}) public Result<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { log.warn("【用实体类接收Body参数时,整个Body缺失、Body参数类型错误或JSON格式错误】{}", e.getMessage()); return Result.fail("Body参数解析失败"); } @ExceptionHandler({MethodArgumentNotValidException.class}) public Result<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { String s = e.getBindingResult().getAllErrors().get(0).getDefaultMessage(); log.info("【用实体类接收Body参数时,校验失败】parameter={{}}, message={}", e.getParameter(), s); return Result.fail(s); } /** * 如果是Path参数缺失,会直接报404错误 */ @ExceptionHandler({MissingServletRequestParameterException.class}) public Result<String> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) { log.warn("【用方法参数接收Query参数时,参数缺失】{}", e.getMessage()); return Result.fail("Query参数缺失"); } @ExceptionHandler({MissingRequestHeaderException.class}) public Result<String> handleMissingRequestHeaderException(MissingRequestHeaderException e) { log.warn("【用方法参数接收Header参数时,参数缺失】parameter={{}}, headerName={}", e.getParameter(), e.getHeaderName()); return Result.fail("Header参数缺失"); } @ExceptionHandler({MissingServletRequestPartException.class}) public Result<String> handleMissingServletRequestPartException(MissingServletRequestPartException e) { log.warn("【用方法参数接收File参数时,参数缺失】{}", e.getMessage()); return Result.fail("File参数缺失"); } @ExceptionHandler({BindException.class}) public Result<String> handleBindException(BindException e) { ObjectError objectError = e.getBindingResult().getAllErrors().get(0); String defaultMessage = objectError.getDefaultMessage(); if (defaultMessage.contains("required type")) { log.warn("【用实体类接收Query参数时,参数类型错误】objectError.getObjectName()={}, objectError.getDefaultMessage()={}", objectError.getObjectName(), defaultMessage); return Result.fail("Query参数类型错误"); } else { log.info("【用实体类接收Query参数时,校验失败】{}", defaultMessage); return Result.fail(defaultMessage); } } @ExceptionHandler({MethodArgumentTypeMismatchException.class}) public Result<String> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) { log.warn("【用方法参数接收Query/Path/Header参数时,参数类型错误】parameter={{}}, name={}, value={}", e.getParameter(), e.getName(), e.getValue()); return Result.fail("参数类型错误"); } @ExceptionHandler({MissingPathVariableException.class}) public Result<String> handleMissingPathVariableException(MissingPathVariableException e) { log.warn("【用方法参数接收Path参数时,参数类型错误的一种特殊情况】{}", e.getMessage()); // 举例:"Required URI template variable 'postId' for method parameter type Integer is present but converted to null" return Result.fail("Path参数类型错误"); } @ExceptionHandler({ConstraintViolationException.class}) public Result<String> handleConstraintViolationException(ConstraintViolationException e) { String s = e.getMessage(); log.info("【用方法参数接收Query/Path/Header参数时,校验失败】{}", s); return Result.fail((s.split(":")[1]).split(",")[0]); } @ExceptionHandler({HttpRequestMethodNotSupportedException.class}) public Result<String> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) { log.warn("【请求Method错误】{}", e.getMessage()); return Result.fail("请求Method错误"); } @ExceptionHandler({HttpMediaTypeNotSupportedException.class}) public Result<String> handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e) { log.warn("【请求Content-Type错误】{}", e.getMessage()); return Result.fail("请求Content-Type错误"); } // 拦截:未登录异常 @ExceptionHandler(NotLoginException.class) public Result handlerException(NotLoginException e) { // 打印堆栈,以供调试 e.printStackTrace(); // 返回给前端 return Result.error("请先登录!"); } // 拦截:缺少角色异常 @ExceptionHandler(NotRoleException.class) public Result handlerException(NotRoleException e) { e.printStackTrace(); return Result.error("您并没有该权限!"); } // 拦截:缺少权限异常 @ExceptionHandler(NotPermissionException.class) public Result handlerException(NotPermissionException e) { e.printStackTrace(); return Result.error("检测当前的密码为默认密码,请先修改密码!"); } // 图片大于20m异常 @ExceptionHandler({MaxUploadSizeExceededException.class}) public Result<String> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e){ log.warn("【请求文件异常错误】{}", e.getMessage()); return Result.fail("文件错误,可能是上传的文件大于20m"); } @ExceptionHandler({Exception.class}) public Result<String> handleOtherException(Exception e) { log.error("【系统未处理的异常】e.getClass().getName()={}, e.getMessage={}", e.getClass().getName(), e.getMessage()); return Result.error(); } }