vate Double salary;
public String getJobType() {
return jobType;
}
public void setJobType(String jobType) {
this.jobType = jobType;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
}
}
使用方式
@PostMapping("/saveUserWithJob")
@ResponseBody
public Response<UserDTO1> saveUserWithJob(@Validated @RequestBody UserDTO1 userDTO){
userDTO.setUserId(100);
Response response = Response.success();
response.setData(userDTO);
return response;
}
测试结果
POST http://127.0.0.1:9999/user/saveUserWithJob
Content-Type: application/json
{
"name": "程序员自由之路",
"age": "16",
"job": {
"jobType": "1",
"salary": "9999.99"
}
}
{
"rtnCode": "1000",
"rtnMsg": "job.salary:必须小于或等于 1000.99"
}
嵌套校验可以结合分组校验一起使用。还有就是嵌套集合校验会对集合里面的每一项都进行校验,例如 List 字段会对这个 list 里面的每一个 Job 对象都进行校验。这个点
在下面的@Valid 和@Validated 的区别章节有详细讲到。
集合校验
如果请求体直接传递了 json 数组给后台,并希望对数组中的每一项都进行参数校验。此时,如果我们直接使用 java.util.Collection 下的 list 或者 set 来接收数据,参数校验并不会生效!我们可以使用自定义 list 集合来接收参数:
包装 List 类型,并声明@Valid 注解
public class ValidationList<T> implements List<T> {
// @Delegate是lombok注解
// 本来实现List接口需要实现一系列方法,使用这个注解可以委托给ArrayList实现
// @Delegate
@Valid
public List 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);
}
//.... 下面省略一系列List接口方法,其实都是调用了ArrayList的方法
}
调用方法
@PostMapping("/batchSaveUser")
@ResponseBody
public Response batchSaveUser(@Validated(value = UserDTO.Default.class) @RequestBody ValidationList<UserDTO> userDTOs){
return Response.success();
}
调用结果
Caused by: org.springframework.beans.NotReadablePropertyException: Invalid property 'list[1]' of bean class [com.csx.demo.spring.boot.dto.ValidationList]: Bean property 'list[1]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:622) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.AbstractNestablePropertyAccessor.getNestedPropertyAccessor(AbstractNestablePropertyAccessor.java:839) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyAccessorForPropertyPath(AbstractNestablePropertyAccessor.java:816) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:610) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
会抛出 NotReadablePropertyException 异常,需要对这个异常做统一处理。这边代码就不贴了。
自定义校验器
在 Spring 中自定义校验器非常简单,分两步走。
自定义约束注解
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {EncryptIdValidator.class})
public @interface EncryptId {
// 默认错误消息
String message() default "加密id格式错误&