别再乱用了,这才是 @Validated 和 @Valid 的真正区别和用法!
弁言
在平常写接口的时分,必要举行参数的校验,假如参数少的话,使用if else还可以,但是参数多的时分,要写一大堆if else校验,敲的太累也不优雅。
以是今天将先容使用注解来举行参数校验,既便利,还优雅。
@valid和@Validated区别
@Validation对@Valid举行了二次封装
区别 | @valid | @validate |
提供者 | spring-boot-starter-web内里,springboot 项目自带 | Spring 做得一个自界说注解,加强了分组功效 |
对否支持分组 | 不支持 | 支持,参数校验时,依据不同的分组接纳不同的校验 |
使用地点 | 布局函数、办法、办法参数、成员属性 | 类、办法、办法参数,不克不及用于成员属性 |
嵌套校验 | 支持,由于可以在成员属性上使用 | 不支持 |
常用注解
- 除了@Null,@ NotNull,@ NotBlank,@NotEmpty这四个外,其他一切的注解,传 null 时都市被当作好效处理
- 注解常用参数值:message(校验不经过反应的信息)
注解 | 验证的数据典范 | 备注 |
Null | 随意典范 | 参数值必需是 Null |
NotNull | 随意典范 | 参数值必需不是 Null |
NotBlank | 只能作用于字符串 | 字符串不克不及为 null,并且字符串长度必需大于0,最少包含一个非空字符串 |
NotEmpty | CharSequence Collection Map Array | 参数值不克不及为null,且不克不及为空 (字符串长度必需大于0,空字符串(“ ”)可以经过校验) |
Size(min,max ) | CharSequence Collection Map Array | 字符串:字符串长度必需在指定的范围内 Collection:聚集轻重必需在指定的范围内 Map:map的轻重必需在指定的范围内 Array:数组长度必需在指定的范围内 |
Pattern(regexp) | 字符串典范 | 验证字符串对否切合正则表达式 |
Min(value) | 整型典范 | 参数值必需大于即是 最小值 |
Max(value) | 整型典范 | 参数值必需小于即是 最大值 |
DecimalMin(value) | 整型典范 | 参数值必需大于即是 最小值 |
DecimalMax(value) | 整型典范 | 参数值必需小于即是 最大值 |
Positive | 数字典范 | 参数值为实数 |
PositiveOrZero | 数字典范 | 参数值为实数或0 |
Negative | 数字典范 | 参数值为正数 |
NegativeOrZero | 数字典范 | 参数值为正数或0 |
Digits(integer,fraction) | 数字典范 | 参数值为数字,且最大长度不凌驾integer位,整数局部最高位不凌驾fraction位 |
AssertTrue | 布尔典范 | 参数值必需为 true |
AssertFalse | 布尔典范 | 参数值必需为 false |
Past | 时间典范(Date) | 参数值为时间,且必需小于 如今时间 |
PastOrPresent | 时间典范(Date) | 参数值为时间,且必需小于或即是 如今时间 |
Future | 时间典范(Date) | 参数值为时间,且必需大于 如今时间 |
FutureOrPresent | 时间典范(Date) | 参数值为时间,且必需大于或即是 如今日期 |
字符串典范 | 被正文的元素必需是电子邮箱地点 |
校验场景
post哀求校验
目标属性校验
- 在入参目标的字段上添加校验注解,好比@Min
- 在哀求目标前方添加注解@Valid
public class User {
private Integer age;
}
public String checkBodyParam( User user){
return "ok";
}
当age=2时,校验不经过,提示年事必需大于10岁
嵌套属性校验
- 在嵌套目标上添加注解valid
- 在哀求目标前方添加注解valid
public class UserClass {
private String className;
private User user;
}
?
public String checkBodyMultilevelParam( UserClass userClass){
return "ok";
}
当age=2时,校验不经过,提示年事必需大于10岁
聚集参数校验
- 类上添加@Validated
- 在哀求目标前方添加注解@valid,用@validate没有后果
public class ParamTestController {
public String checkList( List<User> users) {
return "ok";
}
}
但是假如要分组校验呢,只能用validate,但是validate又没有后果,怎样办呢。
办法一:
新建目标,将list当做属性
缺陷:如此修正的话,哀求的参数布局就会改动.
办法二:
- 完成list
- 在list属性上添加valid注解
如此ValidList与java.util.List的对外功效完全一律,无需改动聚集布局
public class ValidList<E> implements List<E> {
?
private List<E> list = new LinkedList<>();
public int size() {
return list.size();
}
public boolean isEmpty() {
return list.isEmpty();
}
public boolean contains(Object o) {
return list.contains(o);
}
public Iterator<E> iterator() {
return list.iterator();
}
public Object[] toArray() {
return list.toArray();
}
public <T> T[] toArray(T[] a) {
return list.toArray(a);
}
public boolean add(E e) {
return list.add(e);
}
public boolean remove(Object o) {
return list.remove(o);
}
public boolean containsAll(Collection<?> c) {
return list.containsAll(c);
}
public boolean addAll(Collection<? extends E> c) {
return list.addAll(c);
}
public boolean addAll(int index, Collection<? extends E> c) {
return list.addAll(index, c);
}
public boolean removeAll(Collection<?> c) {
return list.removeAll(c);
}
public boolean retainAll(Collection<?> c) {
return list.retainAll(c);
}
public void clear() {
list.clear();
}
public E get(int index) {
return list.get(index);
}
public E set(int index, E element) {
return list.set(index, element);
}
public void add(int index, E element) {
list.add(index, element);
}
public E remove(int index) {
return list.remove(index);
}
public int indexOf(Object o) {
return list.indexOf(o);
}
public int lastIndexOf(Object o) {
return list.lastIndexOf(o);
}
public ListIterator<E> listIterator() {
return list.listIterator();
}
public ListIterator<E> listIterator(int index) {
return list.listIterator(index);
}
public List<E> subList(int fromIndex, int toIndex) {
return list.subList(fromIndex, toIndex);
}
}
?
("checkValidList")
public String checkValidList(@RequestBody @Valid ValidList<User> users) {
return "ok";
}
get哀求参数校验
- 在类上使用@Validated注解
- 在参数前方添加参数校验的注解
public class ParamTestController {
public String checkParam( Integer age) {
return "ok";
}
public String checkPath( String id) {
return "ok";
}
}