分享知识 传递快乐
SpirngBoot升级到2.3之后,hibernate-validator消失,需要手动依赖spring-boot-starter-validation
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.4.3</version>
</dependency>
常用约束说明
- @Null:元素为null
- @NotNull:元素不为null
- @AssertTrue:元素为true
- @AssertFalse:元素为false
- @Min(value):数字的值大于等于指定的最小值
- @Max(value):个数字的值小于等于指定的最大值
- @DecimalMin(value):大数值大于等于指定的最小值
- @DecimalMax(value):大数值小于等于指定的最大值
- @Size(max=,min=):元素的大小在指定的范围内
- @Digits(integer,fraction):元素是一个数字,其值必须在可接受的范围内
- @Past:一个过去的日期
- @Future:一个将来的日期
- @Pattern(regex=,flag=):指定的正则表达式
- @URL:必须是一个URL
- @Email:必须是email格式
- @NotBlank:字符串不能为空
- @NotEmpty:集合不能为空
- @Length:长度必须在指定范围内
- @Valid:对实体类进行校验
实体参数约束
如果成员是实体,需要带上 @Valid注解;
@RestController
@RequestMapping("/demo")
public class SupportController {
@Autowired
private Demo demo;
@PostMapping(value = "/save")
public Result save(@Valid @RequestBody UserReq userReq) {
return demo.save(userReq);
}
}
拼接参数约束
需要在控制层的类上加上 @Validated;
@RestController
@RequestMapping("/demo")
@Validated
public class DemoController {
@Autowired
private Demo demo;
@PostMapping(value = "/list")
public Result list(@NotBlank(message = "userName不能为空") String userName,
@NotBlank(message = "idno不能为空") String idno) {
return demo.list(roomid, msgtime);
}
}
参数嵌套验证
@Data
@ApiModel(value = "User入参")
public class UserReqVO {
@NotBlank(message = "用户名称不能为空")
private String userName;
@Valid
private List<RolesReqVO> rolesReq;
}
异常捕获
全局异常捕获,当出现参数校验不合法时捕获异常,并且返回给前端;
@Slf4j
@RestControllerAdvice
public class DefaultExceptionAdvice {
private Result defHandler(String msg, Exception e) {
log.error(msg, e);
return Result.failed(msg);
}
/**
* 捕获方法参数校验异常
*
* @param exception
* @return
*/
@ExceptionHandler(ConstraintViolationException.class)
public Result constraintViolationExceptionHandler(ConstraintViolationException exception) {
Set<ConstraintViolation<?>> message = exception.getConstraintViolations();
HashMap<String, Object> map = new HashMap<>();
message.stream().forEach(msg -> {
String path = msg.getPropertyPath().toString();
String field = path.substring(path.indexOf(".") + 1);
map.put(field, msg.getMessageTemplate());
});
return Result.failed(map.toString());
}
/**
* 校验Body错误拦截处理
*
* @param exception 错误信息集合
* @return 错误信息
* 返回状态码:500
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result validationBodyException(MethodArgumentNotValidException exception) {
FieldError error = exception.getBindingResult().getFieldError();
String field = error.getField();
String message = String.format("%s:%s", field, error.getDefaultMessage());
return Result.failed(message);
}
}
@validated和@valid不同点
在spring项目中,@validated和@valid功能很类似,都可以在controller层开启数据校验功能。但是@validated和@valid又不尽相同。
有以下不同点:
- @Validated:提供分组功能,可以在参数验证时,根据不同的分组采用不同的验证机制;可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上
- @Valid:没有分组功能;可以用在方法、构造函数、方法参数和成员属性(字段)上。
@validated的使用注意点
- @validated和@valid都可以用在controller层的参数前面,但这只能在controller层生效。
- @validated如果要开启方法验证。注解应该打在类上,而不是方法参数上。
- @validated不支持嵌套验证。所以jsr303标准的注解修饰的对象只能基本类型和包装类型。其他类型只能做到检测是否为空,对于对象里面的jsr303标准的注解修饰的属性,不支持验证。