1、实现方式定义一个全局异常配置类,使用@RestControllerAdvice注解
在使用方法上用
@ExceptionHandler(value = BizException.class)配合使用,使其异常提示作用
2、需要定义一个统一结果返回类,如下代码
@Data
@Slf4j
@ToString
public class CommonResult<T> {/*** 状态码*/private long code;/*** 提示信息*/private String message;/*** 数据封装*/private T data;protected CommonResult() {}protected CommonResult(long code, String message, T data) {this.code = code;this.message = message;this.data = data;}/*** 成功返回结果** @param data 获取的数据*/public static <T> CommonResult<T> success(T data) {return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);}/*** 成功返回结果** @param data 获取的数据* @param message 提示信息*/public static <T> CommonResult<T> success(T data, String message) {return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);}/*** 失败返回结果* @param errorCode 错误码*/public static <T> CommonResult<T> failed(IErrorCode errorCode) {return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);}/*** 失败返回结果* @param errorCode 错误码* @param message 错误信息*/public static <T> CommonResult<T> failed(IErrorCode errorCode,String message) {return new CommonResult<T>(errorCode.getCode(), message, null);}/*** 失败返回结果* @param message 提示信息*/public static <T> CommonResult<T> failed(String message) {return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);}/*** 失败返回结果*/public static <T> CommonResult<T> failed() {return failed(ResultCode.FAILED);}/*** 参数验证失败返回结果*/public static <T> CommonResult<T> validateFailed() {return failed(ResultCode.VALIDATE_FAILED);}/*** 参数验证失败返回结果* @param message 提示信息*/public static <T> CommonResult<T> validateFailed(String message) {return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null);}/*** 未登录返回结果*/public static <T> CommonResult<T> unauthorized(T data) {return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);}/*** 未授权返回结果*/public static <T> CommonResult<T> forbidden(T data) {return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);}
3、需要定义一个统一的错误吗接口,异常枚举类来实现
/*** 错误码接口*/
public interface IErrorCode {/*** 返回码*/long getCode();/*** 返回信息*/String getMessage();
}
/*** 统一返回结果枚举定义*/
public enum ResultCode implements IErrorCode {SUCCESS(200, "操作成功"),FAILED(500, "操作失败"),VALIDATE_FAILED(404, "参数检验失败"),UNAUTHORIZED(401, "暂未登录或token已经过期"),FORBIDDEN(403, "没有相关权限");private long code;private String message;private ResultCode(long code, String message) {this.code = code;this.message = message;}@Overridepublic long getCode() {return code;}@Overridepublic String getMessage() {return message;}
4、自定义业务异常,在业务异常时使用抛出,在全局异常里面处理捕获返回给前端
/*** 自定义业务异常*/
public class BizException extends RuntimeException{private IErrorCode errorCode;public BizException(Throwable cause) {super(cause);}public BizException(IErrorCode code) {super(code.getMessage());this.errorCode = code;}public BizException(String message) {super(message);}public BizException(String message, Throwable cause) {super(message, cause);}public IErrorCode getErrorCode() {return errorCode;}
}
5、定义全局异常处理类
/*** 全局异常处理*/
@RestControllerAdvice
public class GlobalExceptionHandler {/*** 业务异常* @param e* @return*/@ExceptionHandler(value = BizException.class)public CommonResult handle(BizException e) {if (e.getErrorCode() != null) {return CommonResult.failed(e.getErrorCode());}return CommonResult.failed(e.getMessage());}/*** 将请求体解析并绑定到 java bean 时,如果出错,则抛出 MethodArgumentNotValidException 异常* @param e* @return*/@ExceptionHandler(value = MethodArgumentNotValidException.class)public CommonResult handleValidException(MethodArgumentNotValidException e) {BindingResult bindingResult = e.getBindingResult();String message = null;if (bindingResult.hasErrors()) {FieldError fieldError = bindingResult.getFieldError();if (fieldError != null) {message = fieldError.getField()+fieldError.getDefaultMessage();}}return CommonResult.validateFailed(message);}/*** 表单绑定到 java bean 出错时,绑定参数校验异常* @param e* @return*/@ExceptionHandler(value = BindException.class)public CommonResult handleValidException(BindException e) {BindingResult bindingResult = e.getBindingResult();String message = null;if (bindingResult.hasErrors()) {FieldError fieldError = bindingResult.getFieldError();if (fieldError != null) {message = fieldError.getField()+fieldError.getDefaultMessage();}}return CommonResult.validateFailed(message);}@ExceptionHandler(value = SQLSyntaxErrorException.class)public CommonResult handleSQLSyntaxErrorException(SQLSyntaxErrorException e) {String message = e.getMessage();if (StrUtil.isNotEmpty(message) && message.contains("denied")) {message = "演示环境暂无修改权限,如需修改数据可本地搭建后台服务!";}return CommonResult.failed(message);}/*** 必填校验参数缺失错误* @param e* @return*/@ExceptionHandler(value = MissingServletRequestParameterException.class)public CommonResult handleMissingServletException(MissingServletRequestParameterException e) {String message = e.getMessage();if (StrUtil.isNotEmpty(message)) {return CommonResult.validateFailed(message);}return CommonResult.validateFailed(message);}}