使用@Validated校驗List接口參數的兩種方式
注: 不僅限於兩種,此處只列舉了兩種
創建springboot項目, 並添加 spring-boot-starter-validation
jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
定義接口和參數
@RestController
@RequestMapping(value = "/test")
public class TestController {
@PostMapping(value = "/create")
public String test(@RequestBody List<User> users){
return "success";
}
@lombok.Data
public static class User{
@NotNull(message = "用戶id不能爲空")
private Integer userId;
@NotBlank(message = "用戶名字不能爲空")
private String username;
@NotNull(message = "薪資不能爲空")
private Double salary;
}
}
添加校驗
- 直接在參數列表中添加
@Validated
註解(無效)
public String test(@RequestBody @Validated List<User> users)
如上所示,如果我們直接在參數列表中添加校驗註解,如果是User
對象參數是能夠校驗到參數的,如果是List<User>
參數校驗就無效了,該註解只能校驗JavaBean。
- 使用
@Validated
和@Valid
註解(有效) 在Controller類上加上@Validated, 在需要校驗的參數上加上 @Valid, 就可以校驗list裏的實體類的屬性。
@Validated
@RestController
@RequestMapping(value = "/test")
public class TestController {
@PostMapping(value = "/create")
public String test(@RequestBody @Valid List<User> users){
return "success";
}
}
@Validated
和@Valid
註解的區別:
在Controller中校驗方法參數時,使用@Valid和@Validated並無特殊差異(若不需要分組校驗的話)。
@Valid:標準JSR-303規範的標記型註解,用來標記驗證屬性和方法返回值,進行級聯和遞歸校驗。
@Validated:Spring的註解,是標準JSR-303的一個變種(補充),提供了一個分組功能,可以在入參驗證時,根據不同的分組採用不同的驗證機制。
方法級別:
@Validated註解可以用於類級別,用於支持Spring進行方法級別的參數校驗。
@Valid可以用在屬性級別約束,用來表示級聯校驗。
@Validated只能用在類、方法和參數上,而@Valid可用於方法、字段、構造器和參數上。
- 自定義實現一個List
ValidatedList
, 加@Validated
註解(有效)
@RestController
@RequestMapping(value = "/test")
public class TestController {
@PostMapping(value = "/create")
public String test(@RequestBody @Validated ValidatedList<User> users){
return "success";
}
}
@lombok.Data
public class ValidatedList<E> implements List<E> , Serializable {
@Valid
private List<E> list = new LinkedList<>();
@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.containsAll(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);
}
}