最近在重构老项目的代码,发现校验入参占用了很多代码,之前我对这一块的认识局限于使用StringUtils等工具来多个if块进行判断,代码是没什么问题,但是总写这些令人生烦,毕竟写代码也要讲究优雅的嘛,于是呢我就研究了一下JavaEE Api 上的校验类,基本上推翻了我之前对校验注解之类的认识,在这里记录一下所得。
-
@NotNull@NotBlank@NotEmpty这三个注解的区别以及使用@NotNull:校验入参不能为空,无法正确校检长度为0的字符串或以完全为空格的字符串@NotBlank: 包含@NotNull的功能,可以校验字符串内容是否为空@NotEmpty: 校验传入集合是否为空当以上几个注解校验不被满足的时候,就会抛出异常,打印出默认的消息内容,
如
age not be null这样的错误信息想自定义错误信息可以如:
@NotNull(message = "信息不能为空")来定义 -
@Valid的使用如果入参为一个对象,想校验这个对象内容是否正确的时候,会用到1节中所讲的几个注解,
但是此时会有一个问题:如果不使用
@Valid注解,1节中的注解在入参过程中是不生效的,只有保存的时候才会被校验(不排除PO和DTO是同一个对象的情况)当然,这有一个大前提,就是没有其它对入参校验的方法执行。
**所以如果是简单为了让异常报出来而不是直接返回的时候可以用
@Valid** -
自定义校验与错误信息的处理
(1)使用
BindingResult对象接收被@Valid校验不通过的错误信息/** * 使用BindingResult与@Valid配合的方式 * 拿到错误信息,带部分堆栈 */ @PostMapping("/validationTest6") public String validationTest6(@RequestBody @Valid User user, BindingResult result){ if(result.hasErrors()){ //取一条错误信息 ObjectError next = result.getAllErrors().iterator().next(); log.error("error={}", next); //后边可以自己返回错误信息也可以自定义 return next.toString(); } //do somethings return "校验通过"; } /** * 使用BindingResult与@Valid配合的方式 * 只拿到错误信息 */ @PostMapping("/validationTest7") public String validationTest7(@RequestBody @Valid User user, BindingResult result){ if(result.hasErrors()){ //取一条错误信息 ObjectError next = result.getAllErrors().iterator().next(); String defaultMessage = next.getDefaultMessage(); log.error("error={}", defaultMessage); //后边可以自己返回错误信息也可以自定义 return defaultMessage; } //do somethings return "校验通过"; }(2)使用Validator对象,不信赖于
@Valid的实现/** * 使用Validator未抽取工具类时的实现 */ @PostMapping("/validationTest9") public String validationTest9(@RequestBody User user){ ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); Set<ConstraintViolation<User>> validate = validator.validate(user); if(!validate.isEmpty()){ ConstraintViolation<User> next = validate.iterator().next(); String message = next.getMessage(); log.error("error={}",message);
