前言(JSR所有注解列表一览)
注解名 | 注解数据类型 | 注解作用 | 示例 |
---|---|---|---|
AssertFalse | boolean/Boolean | 被注释的元素必须为False | @AssertFalse private boolean success; |
AssertTrue | boolean/Boolean | 被注释的元素必须为True | @AssertTrue private boolean success; |
DecimalMax | BigDecimal/BigInteger/CharSequence/byte/short/int/long及其包装类 | 被注释的值应该小于等于指定的最大值 | @DecimalMax("10") private BigDecimal value; |
DecimalMin | BigDecimal/BigInteger/CharSequence/byte/short/int/long及其包装类 | 被注释的值应该大于等于指定的最小值 | @DecimalMin("10") private BigDecimal value; |
Digits | BigDecimal/BigInteger/CharSequence/byte/short/int/long及其包装类 | integer指定整数部分最大位数,fraction指定小数部分最大位数 | @Digits(integer = 10,fraction = 4) private BigDecimal value; |
CharSequence | 字符串为合法的邮箱格式 | @Email private String email; | |
Future | java中的各种日期类型 | 指定日期应该在当期日期之后 | @Future private LocalDateTime future; |
FutureOrPresent | java中的各种日期类型 | 指定日期应该为当期日期或当期日期之后 | @FutureOrPresent private LocalDateTime futureOrPresent; |
Max | BigDecimal/BigInteger/byte/short/int/long及包装类 | 被注释的值应该小于等于指定的最大值 | @Max("10") private BigDecimal value; |
Min | BigDecimal/BigInteger/byte/short/int/long及包装类 | 被注释的值应该大于等于指定的最小值 | @Min("10") private BigDecimal value; |
Negative | BigDecimal/BigInteger/byte/short/int/long/float/double及包装类 | 被注释的值应该是负数 | @Negative private BigDecimal value; |
NegativeOrZero | BigDecimal/BigInteger/byte/short/int/long/float/double及包装类 | 被注释的值应该是0或者负数 | @NegativeOrZero private BigDecimal value; |
NotBlank | CharSequence | 被注释的字符串至少包含一个非空字符 | @NotBlank private String noBlankString; |
NotEmpty | CharSequence/Collection/Map/Array | 被注释的集合元素个数大于0 | @NotEmpty private List<string> values; |
NotNull | any | 被注释的值不为空 | @NotEmpty private Object value; |
Null | any | 被注释的值必须空 | @Null private Object value; |
Past | java中的各种日期类型 | 指定日期应该在当期日期之前 | @Past private LocalDateTime past; |
PastOrPresent | java中的各种日期类型 | 指定日期应该在当期日期或之前 | @PastOrPresent private LocalDateTime pastOrPresent; |
Pattern | CharSequence | 被注释的字符串应该符合给定得到正则表达式 | @Pattern(\d*) private String numbers; |
Positive | BigDecimal/BigInteger/byte/short/int/long/float/double及包装类 | 被注释的值应该是正数 | @Positive private BigDecimal value; |
PositiveOrZero | BigDecimal/BigInteger/byte/short/int/long/float/double及包装类 | 被注释的值应该是正数或0 | @PositiveOrZero private BigDecimal value; |
Size | CharSequence/Collection/Map/Array | 被注释的集合元素个数在指定范围内 | @Size(min=1,max=10) private List<string> values; |
1.引入JSR的依赖
<!--jsr303-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2.定义实体类和controller
@Data
public class User implements Serializable{
@Email
private String email;
}
如上图,例如我们这里有一个实体类User,里面有一个email字段,并且被@Email注解,接下来开始创建controller接口。
@RestController
@RequestMapping("/user")
@Slf4j
@Validated
public class UserController {
@PostMapping
public Response createUser(@RequestBody @Validated User user){
return Response.ok("成功1");
}
@GetMapping
public Response jsrTest(@NotNull Integer userId,@NotBlank String password,@Email String email) {
System.out.println("userId->"+userId+",password->"+password+",email->"+email);
return Response.ok("成功2");
}
}
如上图,我们创建了一个UserController对象,并且里面有一个post请求和一个get请求(为什么要分开讨论后续讲)。
1.post请求的参数一般是写在body里面的,这种直接在@RequestBody旁边加上 @Validated注解即可,然后在对象中注解清楚规则,比如@NotNull,@NotBlank等。
2.如果是像Get请求那样,作为param的参数,直接在Controller类上加@Validated注解(是类上,非方法上注解),然后在入参前面加上对于的限制条件即可。
3.校验的嵌套校验,校验传递性问题解决
例如上面的user对象,里面只有一个email一个基础属性,如果有其他对象属性的话,如果也需要校验参数的话,那么需要加上@Vaild注解,这样才会嵌套校验。如下图
public class User implements Serializable{
@Email
private String email;
@Valid
//如果不加这一行,那么当校验user对象时候,将不会校验Role这个对象里面的参数是否正常
private Role role;
}
4.统一异常类处理
如果参数不合法,JSR会抛出异常,这里异常有两种,一种是get请求的param的参数,会抛出ConstraintViolationException的异常,第二种是post请求的body的json数据中参数不合法,会抛出MethodArgumentNotValidException的异常,所以在这里,可以使用@ControllerAdvice做统一的异常捕获和处理,完整代码已贴出。
package com.salong.myself.controllerAdvice;
import com.salong.myself.common.response.Response;
import com.salong.myself.common.response.RetCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolationException;
/**
* @author Salong
* @date 2022/7/18 15:03
* @Email:salong0503@aliyun.com
*/
//这里没有指定controller路径和指定类,所有的controller只要抛出下面两个异常就会到这两个方法中
@RestControllerAdvice
@Slf4j
public class JsrAdvice {
//在这里,Response为个人封装的统一返回类
@ExceptionHandler(ConstraintViolationException.class)
public Response queryExceptionHandler(Exception e){
log.warn("捕获到query参数异常:{}",e.getMessage());
return Response.error(RetCode.BAD_REQUEST,e.getMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public Response bodyExceptionHandler(Exception e){
log.warn("捕获到body参数异常:{}",e.getMessage());
return Response.error(RetCode.BAD_REQUEST,e.getMessage());
}
}
最后,展示一下最终成果。