以后的知识点呀、报错修复啥的都改成实习笔记啦,除非我实习期结束啦。这几天鉴权部分基本完成了,老板让我写CRUD,秉承着代码优雅的前提,我开始看参数校验。
你在日常敲代码中,有没有遇到这种情况,前端传到后端的参数多,且大多数都需要校验,这样子你是不是需要很多if来判断他们是否是符合逻辑的。比如:
if(schoolInfo!=null&&schoolInfo.getId()!=null) {
return RestResult.failure();
}
以上举个小例子,这样子写虽然看起来很整齐且易懂,但是参数一多,逻辑还没开始,就一堆if语句在上面,有点不太优雅。
其实springboot官方文档里有推荐使用这个东西来做参数校验,用法也很简单,有兴趣的小伙伴可以去网上搜索下用法,这里举个例子
表示参数必须为空,只需要在实体类的参数上标识即可,您还可以加上报错信息,例如:
@Null(message = "Id存在非法值")
private String id;
标识后,在接收参数的controller上,使用@Validated注解,例如
public RestResult addSchool(@Validated SchoolInfo schoolInfo)
如此,如果id中有值,会报异常,异常错误信息是你在message中填写的字。
如果您将错误信息直接返回的话,会是一大串字符串,这里测试的时候忘记截图了,小伙伴可以自己看看,为了使返回好看一点,有请今天的第二个主角:
首先,我们要知道,在不同情况下,@Validated 返回的异常是不同的,以下:
//处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常,详情继续往下看代码
BindException e
//处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是
ConstraintViolationException e
//处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常。
MethodArgumentNotValidException e
当我们知道这些之后,就可以开始写异常处理:
/**
* 统一异常处理
* jackson
* 时间:2020年04月10日16:03:05
*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public RestResult handle(Throwable e, HttpServletRequest request) {
/**
* 参数校验
*/
if(e instanceof BindException)
return this.BindExceptionHandler((BindException) e);
if(e instanceof ConstraintViolationException)
return this.ConstraintViolationExceptionHandler((ConstraintViolationException) e);
if(e instanceof MethodArgumentNotValidException)
return this.MethodArgumentNotValidExceptionHandler((MethodArgumentNotValidException) e);
}
//处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常,详情继续往下看代码
public RestResult BindExceptionHandler(BindException e) {
log.error("参数异常");
String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
return RestResult.failure(message);
}
//处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException
public RestResult ConstraintViolationExceptionHandler(ConstraintViolationException e) {
log.error("参数异常");
String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining());
return RestResult.failure(message);
}
//处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常。
public RestResult MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
log.error("参数异常");
String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
return RestResult.failure(message);
}
}
如果对统一异常管理不了解的小伙伴,建议去别人的博客观摩观摩,这里controller一旦抛出异常,会被@RestControllerAdvice捕获到,进入逻辑判断,这里比对了三个不同的异常,进行不同的处理。
为了方便小伙伴,我贴下我的返回类
/**
* Description: 返回结果对象
* Author: jackson
* Date: 2020年04月10日10:16:46
**/
@Data
public class RestResult<T> implements Serializable {
private String msg;
private Integer code;
private T data;
Long count;//数据数量
List<T> datas;//返回数据
public RestResult(Integer code, String msg) {
super();
this.code = code;
this.msg = msg;
}
public RestResult(Integer code, String msg,T data) {
super();
this.code = code;
this.msg = msg;
this.data = data;
}
public RestResult(Integer code, String msg, List<T> datas, Long count) {
this.code = code;
this.msg = msg;
this.datas = datas;
this.count = count;
}
/* 无数据传输的 成功返回 */
public static <T> RestResult<T> success() {
return new RestResult<T>( ErrorCode.SUCCESS.getErrorCode(), ErrorCode.SUCCESS.getErrorMsg());
}
// public static RestResult success(String msg) {
// return new RestResult(ErrorCode.SUCCESS.getErrorCode(), msg);
// }
public static <T> RestResult<T> success(ErrorCode errorCode) {
return new RestResult<T>( errorCode.getErrorCode(), errorCode.getErrorMsg());
}
/* 单个数据传输的 成功返回 */
public static <T> RestResult<T> success(T data) {
return new RestResult<T>( ErrorCode.SUCCESS.getErrorCode(), ErrorCode.SUCCESS.getErrorMsg(), data);
}
public static <T> RestResult<T> success(String msg, T data) {
return new RestResult<T>(ErrorCode.SUCCESS.getErrorCode(), msg, data);
}
public static <T> RestResult<T> success(ErrorCode errorCode, T data) {
return new RestResult<T>( errorCode.getErrorCode(), errorCode.getErrorMsg(), data);
}
/* 分页数据传输的 成功返回 */
public static <T> RestResult<T> success(Long count, List<T> datas) {
return new RestResult<T>(ErrorCode.SUCCESS.getErrorCode(),ErrorCode.SUCCESS.getErrorMsg(),datas,count);
}
public static <T> RestResult<T> success(String msg, Long count, List<T> datas) {
return new RestResult<T>(ErrorCode.SUCCESS.getErrorCode(), msg, datas, count);
}
public static <T> RestResult<T> success(ErrorCode resultCode, Long count, List<T> datas) {
return new RestResult<T>( resultCode.getErrorCode(), resultCode.getErrorMsg(), datas ,count);
}
/* 无数据传输的 失败返回 */
public static <T> RestResult<T> failure(String message) {
return new RestResult<T>( ErrorCode.FAILED.getErrorCode(), message);
}
public static <T> RestResult<T> failure() {
return new RestResult<T>( ErrorCode.FAILED.getErrorCode(), ErrorCode.FAILED.getErrorMsg());
}
public static <T> RestResult<T> failure(ErrorCode resultCode) {
return new RestResult<T>( resultCode.getErrorCode(), resultCode.getErrorMsg());
}
public static <T> RestResult<T> failure(CustomizeException c) {
return new RestResult<T>( c.getCode(),c.getMessage());
}
public static <T> RestResult<T> failure(Integer code, String msg) {
return new RestResult<T>( code, msg);
}
}
哎哟,还是觉得自己的异常捕获类写的不太好,不知道有没有大佬指正下。
以上,希望能帮助到小伙伴。