全局异常处理
1.定义一个全局异常枚举类
/**
* 错误参数枚举类
*/
@Getter
public enum GlobalExceptionEnum {
//错误字段
SUCCESS("0", "操作成功!"),
ERROR("-1", "系统异常,请重试!"),
PHONE_NULL_EXCEPTION("1001", "电话不能为空!"),
PARAM_NULL_EXCEPTION("1002", "参数不能为空!"),
;
//错误码
private String code;
//错误信息
private String message;
//构造方法
GlobalExceptionEnum(String code, String message) {
this.code = code;
this.message = message;
}
}
2.抛出全局异常类GlobalException:
@Data
public class GlobalException extends RuntimeException{
//错误码
private String code;
//错误信息
private String globalMessage;
public GlobalException() {
}
public GlobalException(String message) {
super(message);
}
public GlobalException(String code, String message) {
super(message);
this.code = code;
this.globalMessage = message;
}
//接收错误枚举字段
public GlobalException(GlobalExceptionEnum globalExceptionEnum) {
super(globalExceptionEnum.getMessage());
this.code = globalExceptionEnum.getCode();
this.globalMessage = globalExceptionEnum.getMessage();
}
}
4.定义一个AjaxResult类
用于返回信息给前端,其中包括返回成功或者错误信息,成功可以返回状态码、信息和数据,错误也可以返回错误码、信息和数据。
@Data
public class AjaxResult {
private Boolean success = true;
//返回信息
private String message = "操作成功!";
//错误码
private String code = "0";
//返回给前端的数据
private Object data = null;
public AjaxResult() {
}
public static AjaxResult success(){
return new AjaxResult();
}
public static AjaxResult success(String code, String message){
AjaxResult ajaxResult = new AjaxResult();
ajaxResult.setMessage(message);
ajaxResult.setCode(code);
return ajaxResult;
}
public static AjaxResult success(String code, String message, Object data){
AjaxResult ajaxResult = new AjaxResult();
ajaxResult.setMessage(message);
ajaxResult.setCode(code);
ajaxResult.setData(data);
return ajaxResult;
}
public static AjaxResult success(Object data){
AjaxResult ajaxResult = new AjaxResult();
ajaxResult.setData(data);
return ajaxResult;
}
public static AjaxResult error(String code, String message){
AjaxResult ajaxResult = new AjaxResult();
ajaxResult.setSuccess(false);
ajaxResult.setMessage(message);
ajaxResult.setCode(code);
return ajaxResult;
}
public static AjaxResult error(String code, String message, Object data){
AjaxResult ajaxResult = new AjaxResult();
ajaxResult.setSuccess(false);
ajaxResult.setMessage(message);
ajaxResult.setCode(code);
ajaxResult.setData(data);
return ajaxResult;
}
}
3.定义一个全局异常处理器
此处理器实则为一个拦截器,当任何异常信息被捕捉时,就会执行该处理器中的方法,并返回AjaxResult给controller控制器。
package com.zcy.basic.exception;
import com.zcy.basic.utils.AjaxResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.stream.Collectors;
/**
* 此注解包含了两个注解
* @ControllerAdvice:将控制所有的controller层并拦截所有的异常
* @ResponseBody:将本类中所有方法的返回值转换为JSON
*/
@RestControllerAdvice // 必须必须要被启动类扫描
public class GlobalExceptionHandler {
/**
* 处理系统异常
* @return
*
* catch (Exception e) {
* e.printStackTrace();
* return AjaxResult.me().setSuccess(false).setMessage("系统繁忙,请重试!");
* }
*/
@ExceptionHandler(Exception.class) // 这句代码你可以认为是你trycatch中的catch,括号中的字节码就是此方法要捕捉的异常类型
public AjaxResult exceptionHandler(Exception e){
e.printStackTrace();
return AjaxResult.error(GlobalExceptionEnum.ERROR.getCode(), GlobalExceptionEnum.ERROR.getMessage());
}
/**
* 处理业务异常
* @return
*
* catch (GlobalException e) {
* e.printStackTrace();
* return AjaxResult.me().setSuccess(false).setMessage(e.getMessage());
* }
*/
@ExceptionHandler(GlobalException.class)
public AjaxResult globalExceptionHandler(GlobalException e){
e.printStackTrace();
return AjaxResult.error(e.getCode(), e.getGlobalMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public AjaxResult globalExceptionHandler(MethodArgumentNotValidException e){
e.printStackTrace();
// ((BeanPropertyBindingResult) e.bindingResult).errors.get(0).defaultMessage
List<ObjectError> errors = e.getBindingResult().getAllErrors();
// map():对于流的一些中间业务操作就用此方法
// ObjectError::getDefaultMessage:我只要流中对象的defaultMessage
//errors.stream().map(o->o.getDefaultMessage())
// Collectors.joining(","):joining只对字符串生效,用其他类型会报错,把所有的得到的字符串使用逗号进行隔开并组合成一个字符串
String messages = errors.stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(","));
return AjaxResult.error(GlobalExceptionEnum.PARAM_ERROR.getCode(), messages);
}
@ExceptionHandler(ConstraintViolationException.class)
public AjaxResult globalExceptionHandler(ConstraintViolationException e){
e.printStackTrace();
return AjaxResult.error(GlobalExceptionEnum.PARAM_ERROR.getCode(), e.getMessage());
}
}