• SpringBoot集成JSR并使用


    前言(JSR所有注解列表一览)

    注解名注解数据类型注解作用示例
    AssertFalseboolean/Boolean被注释的元素必须为False@AssertFalse private boolean success;
    AssertTrueboolean/Boolean被注释的元素必须为True@AssertTrue private boolean success;
    DecimalMaxBigDecimal/BigInteger/CharSequence/byte/short/int/long及其包装类被注释的值应该小于等于指定的最大值@DecimalMax("10") private BigDecimal value;
    DecimalMinBigDecimal/BigInteger/CharSequence/byte/short/int/long及其包装类被注释的值应该大于等于指定的最小值@DecimalMin("10") private BigDecimal value;
    DigitsBigDecimal/BigInteger/CharSequence/byte/short/int/long及其包装类integer指定整数部分最大位数,fraction指定小数部分最大位数@Digits(integer = 10,fraction = 4) private BigDecimal value;
    EmailCharSequence字符串为合法的邮箱格式@Email private String email;
    Futurejava中的各种日期类型指定日期应该在当期日期之后@Future private LocalDateTime future;
    FutureOrPresentjava中的各种日期类型指定日期应该为当期日期或当期日期之后@FutureOrPresent private LocalDateTime futureOrPresent;
    MaxBigDecimal/BigInteger/byte/short/int/long及包装类被注释的值应该小于等于指定的最大值@Max("10") private BigDecimal value;
    MinBigDecimal/BigInteger/byte/short/int/long及包装类被注释的值应该大于等于指定的最小值@Min("10") private BigDecimal value;
    NegativeBigDecimal/BigInteger/byte/short/int/long/float/double及包装类被注释的值应该是负数@Negative private BigDecimal value;
    NegativeOrZeroBigDecimal/BigInteger/byte/short/int/long/float/double及包装类被注释的值应该是0或者负数@NegativeOrZero private BigDecimal value;
    NotBlankCharSequence被注释的字符串至少包含一个非空字符@NotBlank private String noBlankString;
    NotEmptyCharSequence/Collection/Map/Array被注释的集合元素个数大于0@NotEmpty private List values;
    NotNullany被注释的值不为空@NotEmpty private Object value;
    Nullany被注释的值必须空@Null private Object value;
    Pastjava中的各种日期类型指定日期应该在当期日期之前@Past private LocalDateTime past;
    PastOrPresentjava中的各种日期类型指定日期应该在当期日期或之前@PastOrPresent private LocalDateTime pastOrPresent;
    PatternCharSequence被注释的字符串应该符合给定得到正则表达式@Pattern(\d*) private String numbers;
    PositiveBigDecimal/BigInteger/byte/short/int/long/float/double及包装类被注释的值应该是正数@Positive private BigDecimal value;
    PositiveOrZeroBigDecimal/BigInteger/byte/short/int/long/float/double及包装类被注释的值应该是正数或0@PositiveOrZero private BigDecimal value;
    SizeCharSequence/Collection/Map/Array被注释的集合元素个数在指定范围内@Size(min=1,max=10) private List values;

    1.引入JSR的依赖

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-validationartifactId>
    4. dependency>

    2.定义实体类和controller

    1. @Data
    2. public class User implements Serializable{
    3. @Email
    4. private String email;
    5. }

    如上图,例如我们这里有一个实体类User,里面有一个email字段,并且被@Email注解,接下来开始创建controller接口。

    1. @RestController
    2. @RequestMapping("/user")
    3. @Slf4j
    4. @Validated
    5. public class UserController {
    6. @PostMapping
    7. public Response createUser(@RequestBody @Validated User user){
    8. return Response.ok("成功1");
    9. }
    10. @GetMapping
    11. public Response jsrTest(@NotNull Integer userId,@NotBlank String password,@Email String email) {
    12. System.out.println("userId->"+userId+",password->"+password+",email->"+email);
    13. return Response.ok("成功2");
    14. }
    15. }

    如上图,我们创建了一个UserController对象,并且里面有一个post请求和一个get请求(为什么要分开讨论后续讲)。

    1.post请求的参数一般是写在body里面的,这种直接在@RequestBody旁边加上 @Validated注解即可,然后在对象中注解清楚规则,比如@NotNull,@NotBlank等。

    2.如果是像Get请求那样,作为param的参数,直接在Controller类上加@Validated注解(是类上,非方法上注解),然后在入参前面加上对于的限制条件即可。

    3.校验的嵌套校验,校验传递性问题解决

    例如上面的user对象,里面只有一个email一个基础属性,如果有其他对象属性的话,如果也需要校验参数的话,那么需要加上@Vaild注解,这样才会嵌套校验。如下图

    1. public class User implements Serializable{
    2. @Email
    3. private String email;
    4. @Valid
    5. //如果不加这一行,那么当校验user对象时候,将不会校验Role这个对象里面的参数是否正常
    6. private Role role;
    7. }

    4.统一异常类处理

    如果参数不合法,JSR会抛出异常,这里异常有两种,一种是get请求的param的参数,会抛出ConstraintViolationException的异常,第二种是post请求的body的json数据中参数不合法,会抛出MethodArgumentNotValidException的异常,所以在这里,可以使用@ControllerAdvice做统一的异常捕获和处理,完整代码已贴出。

    1. package com.salong.myself.controllerAdvice;
    2. import com.salong.myself.common.response.Response;
    3. import com.salong.myself.common.response.RetCode;
    4. import lombok.extern.slf4j.Slf4j;
    5. import org.springframework.web.bind.MethodArgumentNotValidException;
    6. import org.springframework.web.bind.annotation.ExceptionHandler;
    7. import org.springframework.web.bind.annotation.RestControllerAdvice;
    8. import javax.validation.ConstraintViolationException;
    9. /**
    10. * @author Salong
    11. * @date 2022/7/18 15:03
    12. * @Email:salong0503@aliyun.com
    13. */
    14. //这里没有指定controller路径和指定类,所有的controller只要抛出下面两个异常就会到这两个方法中
    15. @RestControllerAdvice
    16. @Slf4j
    17. public class JsrAdvice {
    18. //在这里,Response为个人封装的统一返回类
    19. @ExceptionHandler(ConstraintViolationException.class)
    20. public Response queryExceptionHandler(Exception e){
    21. log.warn("捕获到query参数异常:{}",e.getMessage());
    22. return Response.error(RetCode.BAD_REQUEST,e.getMessage());
    23. }
    24. @ExceptionHandler(MethodArgumentNotValidException.class)
    25. public Response bodyExceptionHandler(Exception e){
    26. log.warn("捕获到body参数异常:{}",e.getMessage());
    27. return Response.error(RetCode.BAD_REQUEST,e.getMessage());
    28. }
    29. }

    最后,展示一下最终成果。

  • 相关阅读:
    学习ASP.NET Core Blazor编程系列五——列表页面
    中间件使用注意事项+中间件的分类
    ACL-IJCAI-SIGIR顶级会议论文报告会(AIS 2022)笔记2:分析与可解释性
    在水产养殖中需要用到哪些设备?
    (网络编程)模拟客户端与服务端的交互
    oracle使用regexp_substr来拆分,CONNECT BY LEVEL查询卡死,速度慢的问题。
    应用--WebApplication
    虚拟课堂笔记
    合理编写C++模块(.h、.cc)
    【druid】Connection Close的问题,通过配置Druid的泄露检测机制解决
  • 原文地址:https://blog.csdn.net/qq_35429398/article/details/126015554