@Validated注解对单个实体类与List集合的验证

@Validated对单个实体类的验证

在实体类上属性上添加对应的注解

1
2
3
4
5
6
7
8
9
10
11
@Data
public class NonServiceOrderDTO {
@NotBlank(message="工单编号不能为空")
private String workCode;

@NotBlank(message="设备SN号不能为空")
private String intrserial;

@NotBlank(message="物料编码不能为空")
private String itemId;
}

属性那个注解的含义再文末有说明。

Controller中开启验证

在Controller类的方法参数上,添加@Validated注解,开启验证。

1
2
3
4
5
6
7
@PostMapping("/nonserviceorder")
public Result<Map<String, Object>> noServiceWorkOrder(@RequestBody @Validated NonServiceOrderDTO nonServiceOrderDTO) {

nonServiceOrderService.insertNonOrder(nonServiceOrderDTO);

return new Result<>();
}

自定义异常处理器,捕获错误信息

当验证不通过时会抛异常出来,在全局异常中定义异常处理器。捕获异常信息(因为验证不通过的项可能有多个,所以统一捕获处理),抛给前端。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 异常处理器
*/
@RestControllerAdvice
public class RenExceptionHandler {
/**
* 功能描述: @Validated 校验失败时的异常,将校验结果以json格式返回
* @author wangwren
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result hanleMethodArgumentNotValidException(MethodArgumentNotValidException ex){
BindingResult bindingResult = ex.getBindingResult();
StringBuilder sb = new StringBuilder();
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError fieldError : fieldErrors){
sb.append(fieldError.getDefaultMessage()).append(",");
}
sb.deleteCharAt(sb.lastIndexOf(","));
return new Result().error(500,sb.toString());
}
}

定义一个全局异常处理器,需要加上@RestControllerAdvice注解,上述方法中的Result类是一个通用响应数据。Result.java

@Validated对List集合的验证

今天开发时发现,@Validated只能验证单个实体类,对List集合则不生效,于是上网搜索,把问题解决了,这里就记录一下。

1
2
3
4
5
6
@PostMapping("/assemblageinfo")
public Result<Map<String,Object>> assemblageInfo(@RequestBody @Validated List<AssemblageInfoEntity> assemblageInfoEntities){

assemblageInfoService.insertOrUpdateAssemblage(assemblageInfoEntities);
return new Result<>();
}

这段代码,参数中是List集合,在做参数校验时,并不生效。查网上资料得知,@Valid可以解决这个问题。需要我们自己定义个ValidList类来替换List,就可以达到目的,直接看代码吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package io.renren.utils;

import lombok.Data;

import javax.validation.Valid;
import java.util.*;

/**
* 文件描述: 校验List中字段属性
*
* @author wangwren
* @date 2020年03月16日 11:22
*/
@Data
public class ValidList<E> implements List<E> {

@Valid
private List<E> list = new ArrayList<>();

@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);
}
}

就是在该类中定义一个List,该类实现List的方法,方法中还都是List的实现,只是在类中new 的list上加了@Valid注解就可以了。

剩下的就是将方法中参数List改为自己定义的ValidList就可以实现验证了。

1
2
3
4
5
6
@PostMapping("/assemblageinfo")
public Result<Map<String,Object>> assemblageInfo(@RequestBody @Validated ValidList<AssemblageInfoEntity> assemblageInfoEntities){

assemblageInfoService.insertOrUpdateAssemblage(assemblageInfoEntities);
return new Result<>();
}

其他的与验证单个实体类的操作一样。

@Valid嵌套校验

上述案例就是一个嵌套校验,在一待校验的pojo类中,包含了待验证的对象,需要在待验证的对象上注解@Valid,才能验证待验证对象中的成员属性,这里不能使用@Validated

@Valid与@Validated注解位置上的区别

  • @Valid:用在方法、构造函数、方法参数和成员属性(field)上。
  • @Validated:用在类型、方法和方法参数上。但不能用在成员属性上,用在成员属性上会报错。

其他注解的含义

限制 说明
@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之间
@NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0,集合大小不为0)
@NotBlank 验证注解的元素值不为空(不为null,去除首尾空格长度为0),不同于@NotEmpty,@NotBlank只应用与字符串且在比较时会去除字符串的空格。
@Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式

参考

https://blog.csdn.net/u012693530/article/details/80831408

https://blog.csdn.net/qq_27298687/article/details/104423409

文章作者: wangwren
文章链接: http://wangwren.com/2020/03/Validated注解对单个实体类与List集合的验证/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 DebugDog
打赏
  • 微信

评论