引入依赖pom.xml
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-validationartifactId>
dependency>
注意不用错了类型!
注解 | 限制 |
---|---|
@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之间 【不是数字】 |
@Past | 验证注解的元素值(日期类型)比当前时间早 |
@NotEmpty | 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) |
@NotBlank | 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格 |
验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式 | |
@Length(min = 6, max = 16) | 指定传入的字符串的长度 |
使用的时候例如:
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
public class User implements Serializable {
private static final long serialVersionUID = -5577261004651495987L;
@TableId(type = IdType.AUTO)
private Integer userId;
@NotEmpty
@Length(min = 6, max = 16, message = "密码不能为空") //@Length本身就不允许为空
private String password;
private Integer role;
private String salt;
/**
* 通过邮箱来登录
*/
@Email(regexp = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$")
@NotNull
private String email;
private Date registerTime;
@Override
public String toString() {
String ret = null;
ObjectMapper mapper = new ObjectMapper();
try {
ret = mapper.writeValueAsString(this);
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
}
@Valid
或者@Validated
注解:注意:
spring提供的验证:org.springframework.validation.annotation.Validated;
javax提供的验证:javax.validation.Valid;
@Valid 和 @Validated 都用来触发一次校验, @Valid 是 JSR 303规范的注解, @Validated 是Spring 加强版的注解, 加强的地方有:
@Validated 支持组序列, 该特性用的较少 推荐使用 @Validated 注解.
有几种方法都可以捕获到出现的不匹配情况:
@PostMapping("/login")
public RetJson<Object> login(@Valid @RequestBody User user){
...
}
使用全局异常返回错误信息(就是写在实体类上面的message信息)
@RestControllerAdvice
@Slf4j
public class ExceptionResolver {
/**
* 参数不匹配异常
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = {
MethodArgumentNotValidException.class})
public RetJson methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
log.error("------->MethodArgumentNotValidException参数异常-------- ", e);
return RetJson.fail(ResultCode.VALIDATE_FAILED.getCode(), "参数异常"+e.getBindingResult().getFieldError().getDefaultMessage());
//getDefaultMessage()会返回message信息
}
}
在实体类传参时加上BindingResult
注解:
同时注意
BindingResult
必须紧跟@ModelAttribute的后面
例如:必须写成这种方式:
public String add(@Valid RoleBO role, BindingResult binding,
Maprequest) 写成如下方式,
public String add(@Valid RoleBO role, Maprequest),BindingResult result)
会抛出异常:java.lang.IllegalStateException: An Errors/BindingResult argument is expected to be declared immediately after the model attribute, the @RequestBody or the @RequestPart arguments to which they apply:
其实过程就是:
@PostMapping("/login")
public RetJson<Object> login(@Valid @RequestBody User user, BindingResult result){
if (result.hasErrors()) {
log.error("[login]参数错误:User={}", user);
String s = result.getFieldError().getDefaultMessage();
throw new BaseException(ResultCode.VALIDATE_FAILED.getCode(), s);
}
...
}
这样也可以直接返回message错误的信息。
写一个工具类判断有没有不匹配的情况:
public class ValidatedUtil {
private static Validator validator=
Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory().getValidator();
public static<T> Boolean validate(T v){
Set<ConstraintViolation<T>> set= validator.validate(v);
return set.size() == 0;
}
public static void validData(BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
StringBuilder sb = new StringBuilder();
for (ObjectError error : bindingResult.getAllErrors()) {
sb.append(error.getDefaultMessage());
}
throw new BaseException(ResultCode.VALIDATE_FAILED.getCode(), sb.toString());
}
}
}
@GetMapping("/getEmailCode")
public RetJson<Object> getEmailCode(
@RequestParam("email") @Valid
@Email(regexp = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$", message = "邮箱格式不对") String email) {
//使用全局异常拦截MethodArgumentNotValidException 可以拦截到这个信息
}