hibernate的validate注解异常在不同版本下的全局捕获方式

        在最开始的时候,web项目中接口的第一步几乎都是判断参数的合法性,例如值是否为null等等。因为有guava的工具包,刚开始手写校验参数还OK,例如:      

if (StringUtils.isBlank(name)) {
    return "name不能为空";
}

       随着项目功能接口变多,这种写法越来越麻烦;hibernate出了一种注解,可以很方便地在实体类属性上标注来校验合法性,特别是当springboot出现以后,两者结合完美无缺,也方便返回信息的国际化。

       这种注解写法例如:

@NotEmpty(message = "请求不合法,name不能为空")
private String name;

      然后在接口参数中用@Valid注解标注上面的领域模型,然后参数合法性校验有一个绑定结果叫BindingResult,要想知道是否有错误你还得这么做:

@RequestMapping("/sender/message")
@ResponseBody
public ResponseBean sendMessage(@Valid Message messageBean, BindingResult bindingResult){

    ......

    if (bindingResult.hasErrors()) {
        System.out.println("验证失败!");
    }
    ......
}

     显然每个接口都这么做不够优雅,一般都是在一个针对所有controller的增强全局异常 拦截器中处理通用异常,例如:

@ControllerAdvice
public class ValidateExceptionHandler {

    @ResponseBody
    @ExceptionHandler(BindException.class)
    public Result handleBindException(BindException e) {

        BindingResult bindingResult = e.getBindingResult();

        return Result.fail(Code.ILLIGAL_PARAM_ERROR, bindingResult.getFieldError().getDefaultMessage());
    }

      不过你要注意了,就拿@NotBlank这个注解来说,

javax.validation.constraints.NotBlank和org.hibernate.validator.constraints.NotBlank
这两个包里都有这个注解,他们的校验不通过所抛出的异常也不一样,并且与项目中集成的spring版本也有关系,例如hibernate包中的@NotBlank注解与spring4.0版本及4.0以下版本结合使用,所抛出的异常为:
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResponseResultVO handleMethodArgumentNotValidException(
        MethodArgumentNotValidException ex) {
    BindingResult bindingResult = ex.getBindingResult();
    return ResponseResultVO.fail(Code.ILLIGAL_PARAM_ERROR, bindingResult.getFieldError().getDefaultMessage());
}

     最后,在@Valid注解使用过程中发现@Valid只能作用在参数领域模型上,无法作用在单个属性上;要想作用在单个属性上需要结合spring的@Validate注解与@Min、@Max、@NotBlank等针对单个属性的注解使用,并且@Validate只能加在当前controller类上面,用法例如:

@Validated
@RequestMapping("/user")
@Controller
public class UserController {

   @ResponseBody
   @RequestMapping("/head")
   public Result getHeadThumb(@NotNull(message = "请求不合法,userId不能为空")
                           @Min(value = 0, message = "userId不合法") Long userId, 
                           HttpServletResponse response) {
       ....
   }
}

     @Validate注解在这个包里 org.springframework.validation.annotation.Validated ;而且这种抛出的异常类型为:

@ResponseBody
@ExceptionHandler(ConstraintViolationException.class)
public Result handleConstraintException(ConstraintViolationException ex) {

    return Result.fail(Code.ILLIGAL_PARAM_ERROR, ex.getMessage().split(":")[1]);

}

你可能感兴趣的:(hibernate,spring-boot)