1. @Validated和@Valid的區(qū)別
一般情況下狈谊,若不需要分組校驗的話:使用@Valid和@Validated并無特殊差異缎谷。
- @Valid:標(biāo)準(zhǔn)JSR-303規(guī)范的標(biāo)記型注解啥刻,用來標(biāo)記驗證屬性和方法返回值讶凉,進(jìn)行級聯(lián)和遞歸校驗
- @Validated:Spring的注解税稼,是標(biāo)準(zhǔn)JSR-303的一個變種(補充)身害,提供了一個分組功能赞枕,可以在入?yún)Ⅱ炞C時澈缺,根據(jù)不同的分組采用不同的驗證機(jī)制
- @Validated只能用在類、方法和參數(shù)上炕婶,而@Valid可用于方法姐赡、字段、構(gòu)造器和參數(shù)上
2. 普通校驗
在參數(shù)前加@Valid
注解柠掂,如下:
3. 嵌套校驗
此情況發(fā)生项滑,是由于 方法參數(shù)是JavaBean,參數(shù)的某一個屬性 也是JavaBean
- 在Controller方法參數(shù)上添加
@Valid
注解
- 在Controller方法參數(shù)上添加
public String getInfo(@Valid User u, BindingResult bindingResult) {
system.out.print("hello world");
}
- 在參數(shù)的屬性上添加
@Valid
注解
- 在參數(shù)的屬性上添加
public class User {
@NotBlank
private String name;
@Valid
@NotNull("car不能為空")
private Car car;
}
public class Car {
@NotBlank
private String host;
}
4. 泛型為主要參數(shù)的List對象
若校驗的參數(shù)是List<User>樣式的涯贞,用級聯(lián)嵌套的方法就會失效枪狂。因為@Valid只能校驗JavaBean危喉,而List不是JavaBean。采用以下2個方法可完善:
- 方法1:使用@Validated @Valid
在controller類上面增加@Validated注解州疾,并且刪除方法參數(shù)中的BindingResult bindingResult(因為這個參數(shù)已經(jīng)沒有用了辜限,異常統(tǒng)一有controller返回了)。因為我在 AOP中 用到了BindingResult中的數(shù)據(jù)严蓖,所以我不常用這個方法薄嫡。 - 方法2:自定義一個List工具類ValidList,只在校驗List參數(shù)時使用谈飒,此時他是一個具有List特性的JavaBean
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import javax.validation.Valid;
import cn.hutool.json.JSONUtil;
public class ValidList<E> implements List<E> {
@Valid
private List<E> list = new ArrayList<>();
public List<E> getList() {
return list;
}
public void setList(List<E> list) {
this.list = list;
}
@Override
public int size() {
return list.size();
}
@Override
public boolean isEmpty() {
return list.isEmpty();
}
@Override
public boolean contains(Object o) {
return list.contains(o);
}
@Override
public Iterator<E> iterator() {
return list.iterator();
}
@Override
public Object[] toArray() {
return list.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return list.toArray(a);
}
@Override
public boolean add(E e) {
return list.add(e);
}
@Override
public boolean remove(Object o) {
return list.remove(o);
}
@Override
public boolean containsAll(Collection<?> c) {
return list.contains(c);
}
@Override
public boolean addAll(Collection<? extends E> c) {
return list.addAll(c);
}
@Override
public boolean addAll(int index, Collection<? extends E> c) {
return list.addAll(index, c);
}
@Override
public boolean removeAll(Collection<?> c) {
return list.removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
return list.retainAll(c);
}
@Override
public void clear() {
list.clear();
}
@Override
public E get(int index) {
return list.get(index);
}
@Override
public E set(int index, E element) {
return list.set(index, element);
}
@Override
public void add(int index, E element) {
list.add(index, element);
}
@Override
public E remove(int index) {
return list.remove(index);
}
@Override
public int indexOf(Object o) {
return list.indexOf(o);
}
@Override
public int lastIndexOf(Object o) {
return list.lastIndexOf(o);
}
@Override
public ListIterator<E> listIterator() {
return list.listIterator();
}
@Override
public ListIterator<E> listIterator(int index) {
return list.listIterator(index);
}
@Override
public List<E> subList(int fromIndex, int toIndex) {
return list.subList(fromIndex, toIndex);
}
@Override
public String toString() {
String str = "[";
for (E e : list) {
str += JSONUtil.parse(e).toJSONString(0);
str += ",";
}
return str + "]";
}
}
controller對應(yīng)的方法參數(shù)岂座,使用ValidList
public String getInfo(@Valid ValidList<User> userList, BindingResult bindingResult) {
system.out.print("hello world");
}