SpringBoot Hibernate Validation 数据校验-异常处理

上接:SpringBoot Hibernate Validation 数据校验(参数验证、@Validated)

说明

不符合校验规则时,默认 直接抛出异常,那么就定义全局异常处理

也可以在 controller方法 中处理

全局异常处理

抛出异常

  • 校验方法的形参(字符串类型):不符合校验规则,会抛出 ConstraintViolationException 异常

  • 形参是 bean 类型,分下面两种情况:

    • 形参 bean 前面 没有加 @RequestBody,导致无法给bean赋值,会抛出 BindException 异常

    • 如果 不符合 bean 中的校验规则,会抛出 MethodArgumentNotValidException 异常

关键代码

// 对 SpringBoot Hibernate Validation 抛出的异常做处理
@ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class})
public JsonResult handleValidatedException(Exception e) {
    Set<ConstraintViolation<?>> constraintViolations = null;
    // controlle方法参数是javabean,且不符合验证抛出的异常
    if (e instanceof MethodArgumentNotValidException) {
        MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;
        constraintViolations = ex.getAllErrors();
    } else if (e instanceof ConstraintViolationException) { // controlle方法参数是字符串或基本数据类型,且不符合验证抛出的异常
        ConstraintViolationException ex = (ConstraintViolationException) e;
        constraintViolations = ex.getConstraintViolations();
    } else if (e instanceof BindException) { // 不加@RequestBody注解,提交json数据时,报此异常
        BindException ex = (BindException) e;
        constraintViolations = ex.getAllErrors();
    }
    String message = HibernateValidatorUtil.getMessage(constraintViolations);
    JsonResult resp = JsonResult.fail(HttpStatus.BAD_REQUEST.value(), message );
    return resp;
}

完整代码

package top.malaoshi.netdisk.ctrl;

import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import top.malaoshi.netdisk.exception.BaseException;
import top.malaoshi.netdisk.vo.JsonCodeMsg;
import top.malaoshi.netdisk.vo.JsonResult;
import top.malaoshi.validation.HibernateValidatorUtil;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.Set;

@RestControllerAdvice
public class GlobalExceptionHandler {

    // 对 SpringBoot Hibernate Validation 抛出的异常做处理
    @ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class})
    public JsonResult handleValidatedException(Exception e) {
        Set<ConstraintViolation<?>> constraintViolations = null;
        // controlle方法参数是javabean,且不符合验证抛出的异常
        if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;
            constraintViolations = ex.getAllErrors();
        } else if (e instanceof ConstraintViolationException) { // controlle方法参数是字符串或基本数据类型,且不符合验证抛出的异常
            ConstraintViolationException ex = (ConstraintViolationException) e;
            constraintViolations = ex.getConstraintViolations();
        } else if (e instanceof BindException) { // 不加@RequestBody注解,提交json数据时,报此异常
            BindException ex = (BindException) e;
            constraintViolations = ex.getAllErrors();
        }
        String message = HibernateValidatorUtil.getMessage(constraintViolations);
        JsonResult resp = JsonResult.fail(HttpStatus.BAD_REQUEST.value(), message );
        return resp;
    }

    @ExceptionHandler(BaseException.class)
    public JsonResult handlerBaseException(BaseException e) {
        e.printStackTrace();
        JsonResult res=new JsonResult(e.getCode(),e.getMessage());
        return res;
    }
    //当Controller抛出异常时,由该方法处理
    @ExceptionHandler(Exception.class)
    public JsonResult handlerException(Exception e) {

        e.printStackTrace();//为了便于找到错误
        String msg = e.getMessage();
        if(msg == null || "".equals(msg)){
            msg = e.toString();
        }
        JsonResult res=new JsonResult(JsonCodeMsg.SERVER_ERROR.getCode(), msg);

        return res;
    }

}

controller方法中处理

不符合校验规则时,想在 controller方法 中处理,而不想直接抛出异常,那么就添加一个参数 BindingResult,如下:

@RequestMapping("/saveUserInfo")
public UserInfo saveUserInfo(@Valid UserInfo userInfo, BindingResult bindingResult){
    if(bindingResult.hasErrors()){
        System.out.println("有异常信息");
        for (ObjectError error : bindingResult.getAllErrors()) {
            System.out.println(error.getDefaultMessage());
        }
        return null;
    }
    //save userInfo:将userInfo进行保存
    //userInfoService.save(userInfo);
    return userInfo;
}

原文出处:/show_1IX759F5VBeO.html