校验注解
注解 | 说明 |
---|---|
@Null | 限制只能为null |
@NotNull | 限制必须不为null |
@AssertTrue | 限制必须为true |
@AssertFalse | 限制必须为false |
@Min(value) | 限制必须为一个不小于指定值的数字 |
@Max(value) | 限制必须为一个不大于指定值的数字 |
@DecimalMin(value) | 限制必须为一个不小于指定值的数字 |
@DecimalMax(value) | 限制必须为一个不大于指定值的数字 |
@Digits(integer,fraction) | 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction |
@Past | 限制必须是一个过去的日期 |
@Future | 限制必须是一个将来的日期 |
@Size(max,min) | 限制字符长度必须在min到max之间 |
@Pattern(value) | 限制必须符合指定的正则表达式 |
@NotEmpty | 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) |
@NotBlank | 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格 |
验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式 |
Spring Boot 2.3.0 后需要加该依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
对 User 类校验
public class User {
@NotNull(message = "用户id不能为空")
private Integer id;
@NotBlank(message = "用户名称不能为空")
@Size(min = 2, max = 10, message = "用户名称长度在2~10之间")
private String name;
@NotNull(message = "用户年龄不能为空")
@Max(value = 150,message = "用户年龄不能大于150")
@Min(value = 0,message = "用户年龄大于等于0")
private Integer age;
@NotBlank(message = "用户地址不能为空")
private String address;
// getter setter
}
UserController
对象校验 @Valid 要加在参数旁,path和参数校验 @Validated 要加在类上
@RestController
@RequestMapping("/user")
@Validated
public class UserController {
private Map<Integer, User> userMap = new HashMap<>();
/**
* 对象校验 @Valid 要加在参数旁
* @param user
*/
@PostMapping("/add")
public void add(@RequestBody @Valid User user) {
userMap.put(user.getId(), user);
}
/**
* path校验 @Validated 要加在类上
* @param id
* @return
*/
@GetMapping("/get/{id}")
public User getByPath(@PathVariable("id") @Min(value = 0,message = "id必须大于0") Integer id) {
return userMap.get(id);
}
/**
* 参数校验 @Validated 要加在类上
* @param id
* @return
*/
@GetMapping("/get")
public User getByParam(@Min(value = 0,message = "id必须大于0") Integer id) {
return userMap.get(id);
}
}
统一异常处理
@ControllerAdvice 控制器增强,而@RestControllerAdvice相当于@ResponseBody + @ControllerAdvice。
@ExceptionHandler 能拦截特定异常并统一处理,@ResponseStatus 修改Response中的Http状态。
@RestControllerAdvice
public class GlobalExceptionHandler {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 对象校验 抛出 MethodArgumentNotValidException 异常
* @param exception
* @return
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map validationBodyException(MethodArgumentNotValidException exception) {
BindingResult bindingResult = exception.getBindingResult();
StringBuilder stringBuilder = new StringBuilder();
if (bindingResult.hasErrors()) {
List<ObjectError> errorList = bindingResult.getAllErrors();
errorList.forEach(error -> {
logger.error(error.toString());
stringBuilder.append(error.getDefaultMessage()).append(",");
});
}
Map<String, Object> map = new HashMap<>(2);
map.put("code", 400);
map.put("message", stringBuilder.toString().substring(0, stringBuilder.lastIndexOf(",")));
return map;
}
/**
* path,参数校验 抛出 ConstraintViolationException 异常
* @param exception
* @return
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(ConstraintViolationException.class)
public Map validationPathException(ConstraintViolationException exception) {
Set set = exception.getConstraintViolations();
StringBuilder stringBuilder = new StringBuilder();
if (!set.isEmpty()) {
set.forEach(error -> {
ConstraintViolation constraintViolation = (ConstraintViolation) error;
logger.error(constraintViolation.toString());
stringBuilder.append(constraintViolation.getMessage()).append(",");
});
}
Map<String, Object> map = new HashMap<>(2);
map.put("code", 400);
map.put("message", stringBuilder.toString().substring(0, stringBuilder.lastIndexOf(",")));
return map;
}
}
测试
对象校验
path参数校验
参数校验
参考:
Validation in Spring Boot
All You Need To Know About Bean Validation With Spring Boot
Spring Boot 数据校验@Validated+统一异常处理
Spring Validation最佳实践及其实现原理