引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>2.0.1</version>
</dependency>
常用校验注解
@Null(groups={Add.class}) 参数必须为null,group设置分组,默认为default
@NotNull 参数不为null
@NotEmpty 参数不为null 且不为空集合,集合不为空
@NotBlank 参数不为null且不为空串,只能作用字符串类型
@AssertFalse 被注释的元素必须是false
@AssertTrue 被注释的元素必须是true
@Min(value) 被注释的元素必须为一个数字 >=
@Max(value) 被注释的元素必须为一个数字 <=
@DecimalMin(“value”) >=
@DecimalMax(“value”) <=
@NegativeOrZero <=0
@Range(min,max) 被注释的元素大小必须在指定的范围内
@Size(min ,max) 被注释的元素大小必须在指定的范围内
@Email 被注释的元素必须是电子邮箱地址
@Past 被注释的元素必须是一个过去的日期
@PastOrPresent 被注释的元素必须是一个过去的时间
@Future 被注释的元素必须是一个将来的日期
@Pattern(regexp = “1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$”) 被注释的元素必须是符合指定的正则表达式
@URL 被注释的元素必须是链接地址
提示:除了@NotNull注解之外,其他参数校验注解只有参数不为空的时候才生效
一般校验注解都有一个message的属性,这个属性代表的是注解校验不通过时返回的错误提示。
在controller层方法参数使用校验注解
- 首先需要在controller类上面加上@Validated注解。
- 在参数前面加上校验注解。如@NotBlank(message = “名字不能为空”) String name
上述注解的包:
org.springframework.validation.annotation.Validated;
javax.validation.constraints.NotBlank;
注解参数:message,当不满足校验条件的时候会抛出ConstraintViolationException异常,异常中会包含该message对应的内容----名字不能为空。
import org.springframework.validation.annotation.Validated;
import java.util.*;
@RestController
@Validated
public class TestController extends JeecgController<Test, TestService> {
@PostMapping(value = "/test")
Result<?> test(@RequestBody @NotBlank(message = "名字不能为空") String name,
@NotNull(message = "年龄不能为空") @Max(value = 30,message = "最大不能超过30") @Min(value = 18,message = "最小不能小于18") Integer age) {
return null;
}
}
效果(已处理)
在controller层的DTO对象使用校验注解
- 首先需要在controller类上面加上@Validated注解。
- 在对象参数前面加上@Valid注解,并在对象内使用校验注解
- 如果对象参数内部还嵌套这其他对象,需要在对象属性上面加上@Valid注解(这条和第二条原理差不多)
不满足对象内的校验时,会抛出MethodArgumentNotValidException异常
上述注解的包:
org.springframework.validation.annotation.Validated;
javax.validation.Valid;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import java.util.*;
@RestController
@Validated
public class TestController extends JeecgController<Test, TestService> {
@PostMapping(value = "/test")
Result<?> test(@RequestBody @Valid TestDTO testDTO) {
return testService.test(testDTO);
}
}
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.List;
@Data
@ApiModel(value = "testDTO")
public class TestDTO {
@ApiModelProperty(value = "用户id",required = true)
@NotBlank(message = "用户id不能为空")
private String userId;
@ApiModelProperty(value = "订单id列表",required = true)
@Size(min = 1, message = "至少要选择一个订单")
private List<String> orderIdList;
@ApiModelProperty(value = "是否通知顾客",required = true)
@NotNull(message = "是否通知顾客不能为空")
private Boolean notifyCustomer;
}
效果(已处理)
校验失败返回
一般来说,项目都会定好响应体的结构,直接抛异常返回的信息和预期不太符合。
这个时候就需要我们来全局精准捕获该异常并处理异常信息,按照符合标准的方式返回。
@RestControllerAdvice
@Slf4j
public class ExceptionHandler {
/**
* 这个异常在校验不通过的时候就会抛出
*
* @param e
* @return: Result<?>
**/
@ExceptionHandler({MethodArgumentNotValidException.class, ConstraintViolationException.class})
public Result<?> handleMethodArgumentNotValidException(Exception e) {
log.info("全局捕获校验注解异常e={}", e.getMessage());
BindingResult bindingResult=null;
Result<?> res= Result.ok();
StringBuilder errorInfo = new StringBuilder();
if(e instanceof MethodArgumentNotValidException){
MethodArgumentNotValidException notValidException=(MethodArgumentNotValidException) e;
bindingResult = notValidException.getBindingResult();
List<FieldError> fieldErrorList= bindingResult.getFieldErrors();
String msg = fieldErrorList.stream().map(FieldError::getDefaultMessage).collect(Collectors.joining(","));
return res.error511(msg);
}else if(e instanceof ConstraintViolationException){
ConstraintViolationException violationException=(ConstraintViolationException) e;
Set<ConstraintViolation<?>> constraintViolations = violationException.getConstraintViolations();
String msg = constraintViolations.stream().map(o -> String.valueOf(o.getMessage())).collect(Collectors.joining(","));
return res.error511(msg);
}else{
return res.error511(e.getMessage());
}
}
处理后:
参考:https://blog.csdn.net/qq_42956993/article/details/129199922