在项目中,如果没有进行全局异常捕获,项目运行时遇到问题,返回给用户的结果状态码是500,并且会直接将错误信息展示到用户面前,给用户带来不好的体验。 在SpringBoot项目中,使用以下三个注解可以实现全局异常捕获功能。
全局异常捕获涉及三部分代码,统一状态码的枚举类,统一返回结果的响应类,全局异常和具体异常捕获类。
import lombok.Data;
import lombok.Getter;
public enum CommonStatusEnum {
/**
* token 错误码: 1100 - 1199
*/
TOKEN_VALID(1100, "Token 无效"),
/**
* 用户错误码 1200 -1299
*/
USER_NOT_EXISTS(1200, "当前用户不存在"),
/**
* 成功
*/
SUCCESS(1, "success"),
/**
* 失败
*/
FAILE(0, "统一异常:fail");
@Getter
private int code;
@Getter
private String value;
CommonStatusEnum(int code, String value){
this.code = code;
this.value = value;
}
}
import lombok.ConfigurationKeys;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true) // 支持链式编程
public class ResponseResult<T> {
private int code;
private String message;
private T data;
/**
* 成功响应有数据的方法
* @param data
* @return
* @param <T>
*/
public static <T> ResponseResult success(T data){
// 链式编程
return new ResponseResult().setCode(CommonStatusEnum.SUCCESS.getCode()).setMessage(CommonStatusEnum.SUCCESS.getValue()).setData(data);
}
/**
* 成功响应默认没有数据的方法
* @return
* @param <T>
*/
public static <T> ResponseResult success(){
return new ResponseResult().setCode(CommonStatusEnum.SUCCESS.getCode()).setMessage(CommonStatusEnum.SUCCESS.getValue());
}
/**
*
* @param data
* @return
* @param <T>
*/
public static <T> ResponseResult fail(T data){
return new ResponseResult().setData(data);
}
/**
* 自定义失败 错误码 和 提升信息
* @param code
* @param message
* @return
*/
public static ResponseResult fail(int code, String message){
return new ResponseResult().setCode(code).setMessage(message);
}
/**
* 自定义失败 错误码 和 提示信息 和 数据
* @param code
* @param message
* @param data
* @return
*/
public static ResponseResult fail(int code , String message, String data){
return new ResponseResult().setCode(code).setMessage(message).setData(data);
}
}
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 统一异常处理类
*/
@RestControllerAdvice
@Order(99)
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseResult exceptionHandler(Exception e) {
e.printStackTrace();
return ResponseResult.fail(CommonStatusEnum.FAILE.getCode(), CommonStatusEnum.FAILE.getValue());
}
}
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;
/**
*参数校验异常处理类
*/
@RestControllerAdvice
@Order(1)
public class GlobalValidationExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseResult validationExceptionHandler(MethodArgumentNotValidException e){
return ResponseResult.fail(CommonStatusEnum.VALIDATION_EXCEPTION.getCode(), e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
}
@ExceptionHandler(ConstraintViolationException.class)
public ResponseResult validationExceptionHandler(ConstraintViolationException e){
System.out.println(e);
String message = "";
Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
for (ConstraintViolation<?> c : constraintViolations) {
message = c.getMessageTemplate();
}
return ResponseResult.fail(CommonStatusEnum.VALIDATION_EXCEPTION.getCode(), message);
}
}