@Validated和@Valid校验参数、级联属性、List
@Validated和@Valid的区别
在Controller中校验⽅法参数时,使⽤@Valid和@Validated并⽆特殊差异(若不需要分组校验的话):
@Valid:标准JSR-303规范的标记型注解,⽤来标记验证属性和⽅法返回值,进⾏级联和递归校验
@Validated:Spring的注解,是标准JSR-303的⼀个变种(补充),提供了⼀个分组功能,可以在⼊参验证时,根据不同的分组采⽤不同的验证机制
⽅法级别:
@Validated注解可以⽤于类级别,⽤于⽀持Spring进⾏⽅法级别的参数校验。@Valid可以⽤在属性级别约束,⽤来表⽰级联校验。
@Validated只能⽤在类、⽅法和参数上,⽽@Valid可⽤于⽅法、字段、构造器和参数上
内置的验证约束注解:
空检查
@Null 验证对象是否为null
@NotNull 验证对象是否不为null, ⽆法查检长度为0的字符串
@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否⼤于0,只对字符串,且会去掉前后空格.
@NotEmpty 检查约束元素是否为NULL或者是EMPTY.
Booelan检查
@AssertTrue 验证 Boolean 对象是否为 true
@AssertFalse 验证 Boolean 对象是否为 false
长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
@Length(min=, max=) Validates that the annotated string is between min and max included.
⽇期检查
@Past 验证 Date 和 Calendar 对象是否在当前时间之前
@Future 验证 Date 和 Calendar 对象是否在当前时间之后
@Pattern 验证 String 对象是否符合正则表达式的规则
数值检查,建议使⽤在Stirng,Integer类型,不建议使⽤在int类型上,因为表单值为“”时⽆法转换为int,但可以转换为Stirng
为"",Integer为null
@Min 验证 Number 和 String 对象是否⼤等于指定的值
@Max 验证 Number 和 String 对象是否⼩等于指定的值
@DecimalMax 被标注的值必须不⼤于约束中指定的最⼤值. 这个约束的参数是⼀个通过BigDecimal定义的最⼤值的字符串表⽰.⼩数存在精度
@DecimalMin 被标注的值必须不⼩于约束中指定的最⼩值. 这个约束的参数是⼀个通过BigDecimal定义的最⼩值的字符串表⽰.⼩数存在精度
@Digits 验证 Number 和 String 的构成是否合法
@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定⼩数精度。
@Range(min=, max=) 检查数字是否介于min和max之间.
@Range(min=10000,max=50000,message=“range.bean.wage”)
private BigDecimal wage;
@Valid 递归的对关联对象进⾏校验, 如果关联对象是个集合或者数组,那么对其中的元素进⾏递归校验,如果是⼀个map,则对其中的值部分进⾏校验.(是否进⾏递归验证)
@CreditCardNumber信⽤卡验证
@Email 验证是否是邮件地址,如果为null,不进⾏验证,算通过验证。
@ScriptAssert(lang= ,script=, alias=)
@URL(protocol=,host=, port=,regexp=, flags=)
限制 说明
@Null 限制只能为null
@NotNull 限制必须不为null
@AssertFalse 限制必须为false
@AssertTrue 限制必须为true
@DecimalMax(value) 限制必须为⼀个不⼤于指定值的数字
@DecimalMin(value) 限制必须为⼀个不⼩于指定值的数字
@Digits(integer,fraction) 限制必须为⼀个⼩数,且整数部分的位数不能超过integer,⼩数部分的位数不能超过fraction
@Future 限制必须是⼀个将来的⽇期
@Max(value) 限制必须为⼀个不⼤于指定值的数字
@Min(value) 限制必须为⼀个不⼩于指定值的数字
@Past 限制必须是⼀个过去的⽇期
@Pattern(value) 限制必须符合指定的正则表达式
@Size(max,min) 限制字符长度必须在min到max之间
@Past 验证注解的元素值(⽇期类型)⽐当前时间早
@NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0、集合⼤⼩不为0)
@NotBlank 验证注解的元素值不为空(不为null、去除⾸位空格后长度为0),不同于@NotEmpty,@NotBlank只应⽤于字符串且在⽐较时会去除字符串的空格
@Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定⾃定义的email格式
校验参数、级联属性
1、校验参数
当⼊参为实体对象时,需要在⽅法上加@Valid或@Validated或者在参数前加@Valid或@Validated,或者在类上加@Validated
@Valid
@GetMapping("/exam-info")
public Boolean getInfo(User user){…}
@GetMapping("/exam-info")
public Boolean getInfo(@Valid User user){…}
@Validated
@GetMapping("/exam-info")
public Boolean getInfo(User user){…}
@GetMapping("/exam-info")
public Boolean getInfo(@Validated User user){…}
public Class User{
@NotNull(“id不能为空”)
private Integer id;
}
2、嵌套验证
@valid作⽤于属性上有嵌套验证作⽤,@validated不能作⽤于属性上,如下代码在User类的属性car上添加@valid注解,当传参id为空时会报错。
@GetMapping("/exam-info")
public Boolean getInfo(@Valid User user){…}
public class User{
@Valid
@NotNull(“car不能为空”)
private Car car;
}
public class Car{
@NotNull(“id不能为空”)
private Integer id;
}
校验List
@Valid只能校验JavaBean,⽽List不是JavaBean所以校验会失败,介绍三种解决办法
⽅法1:对List进⾏Wrapper
既然List不是JavaBean,那我们就把它封装成JavaBean,我们定义⼀个ListWrapper类如下:
import lombok.Getter;
import lombok.Setter;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
@Setter
@Getter
public class ListWrapper {
@Valid
private List list;
public ListWrapper() {
list = new ArrayList<>();
}
bigdecimal转换为integer
public  ListWrapper(List<E> list) {
this.list = list;
}
}
同时修改⼀下controller对应的⽅法:
// 使⽤包装类对list进⾏验证
@PostMapping("/insert/all")
public ServerResponse<String> insertList(@Valid @RequestBody ListWrapper<UserEntity> listWrapper, BindingResult bindingResult) {    if(bindingResult.hasErrors()) {
<(FieldError().toString());
FieldError().getDefaultMessage());
}
userService.List());
ateBySuccess();
}
这样就可以对list进⾏校验了
注意:
由于对list进⾏了包装,如果我们传参的时候
[{},{}…]要改为{“list”: [{},{}…]}
⽅法2:使⽤@Validated @Valid
在controller类上⾯增加@Validated注解,并且删除⽅法参数中的BindingResult bindingResult(因为这个参数已经没有⽤了,异常统⼀有controller返回了)
然后我们运⾏⼀下测试⼀下
可以看到可以对参数进⾏校验了,但还还有⼀个问题,那就是这个不是我们想要的返回格式,它controller⾃⼰返回的格式,所以我们需要做⼀个统⼀异常处理,代码如下:
import com.wyq.firstdemomon.ServerResponse;
slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;
@Slf4j
@RestControllerAdvice
public class ControllerExceptionHandler {
@ExceptionHandler
@ResponseBody
public ServerResponse<String> handle(ConstraintViolationException exception) {    (String.valueOf(exception));
Set<ConstraintViolation<?>> violations = ConstraintViolations();    StringBuilder builder = new StringBuilder();
for (ConstraintViolation violation : violations) {
builder.Message());
break;
}
String());
}
}
经过统⼀异常处理,我们这边的返回结果就是我们想要的格式了
⽅法3:⾃定义⼀个List
先上代码后说明,先定义⼀个ValidList
import javax.validation.Valid;
import java.util.*;
public class ValidList implements List {

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。