欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

springboot中使用Hibernate-Validation校验参数详解,

来源: javaer 分享于  点击 48939 次 点评:131

springboot中使用Hibernate-Validation校验参数详解,


目录
  • 1、说明
  • 2、Bean Validation与Hibernate Validation
    • 2.1 Bean Validation中内置的constraint
    • 2.1 Hibernate Validation中添加的constraint
  • 3、基于Hibernate Validation的实现
    • 4、编译器校验工具

      1、说明

      后端接口设计时候,需要对前端请求参数进行'先校验后处理业务'情况,如果在业务代码中通过类似if这里逐个校验,会使得代码变得繁琐,开发工作者都是爱偷懒的。java中,Bean ValidationJavaBean的验证定义了相关的元数据模型和API。

      基于Bean-Validation封装,提供了更加丰富的Hibernate-Validation的校验包。也有开发会把这类校验交给前端来处理,但是接口暴露外网会存在直接调用情况(黄牛)。毕竟:前端校验是为了提高用户的体验度,后端校验则是为了保证数据的安全性

      优点

      1.验证逻辑与业务逻辑之间进行了分离,降低了程序耦合度

      2.统一且规范的验证方式,无需你再次编写重复的验证代码

      3.你将更专注于你的业务,将这些繁琐的事情统统丢在一边

      2、Bean Validation与Hibernate Validation

      2.1 Bean Validation中内置的constraint

      包位置路径:javax.validation.constraints

      注解说明
      @AssertFalse注释的元素必须为False
      @AssertTrue注释的元素必须为True
      @Email注释的元素必须邮箱
      @NotBlank注释的元素不能为空,!null && size>0
      @NotEmpty注释的元素不能为空,数组,集合等
      @NotNull注释的元素必须为空,但可以为""字符串
      @DecimalMin注释的元素数字,最小不得小于Min
      @DecimalMax注释的元素为数字,最大不超过Max值

      其中NotNull、NotEmpty、NotBlank区别

      • @NotNull
        适用于基本数据类型(Integer,Long,Double等等),当 @NotNull 注解被使用在 String 类型的数据上,则表示该数据不能为 Null(但是可以为 Empty)
      • @NotBlank
        适用于 String 类型的数据上,加了@NotBlank 注解的参数不能为 Null 且 trim() 之后 size > 0
      • @NotEmpty
        适用于 String、Collection集合、Map、数组等等,加了@NotEmpty 注解的参数不能为 Null 或者 长度为 0

      2.1 Hibernate Validation中添加的constraint

      注解说明
      @Length注释的元素字符串长度必须为制定返回内
      @Range注释的元素必须在指定范围内
      @URL注释的元素必须为链接

      3、基于Hibernate Validation的实现

      (1)pom包引用
      查看spring-boot-start-web中已经集成了Hibernate Validation,所以可以不用额外引用包。同时spring-boot-start-validation也完成了Hibernate Validationstart封装(校验机制更加全面)。

       <dependency>
              <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-validation</artifactId>
             <version>2.2.6.RELEASE</version>
      </dependency>

      (2)Bean对象中使用注解注释

           ...
          @ApiModelProperty(value = "收货人所在省",required = true)
          @NotNull(message = "省不能为空")
          private String recipientProvince;
      
          @ApiModelProperty(value = "收货人所在市")
          @NotNull(message = "市不能为空")
          private String recipientCity;
      
          @ApiModelProperty(value = "收货人所在区")
          @NotNull(message = "区不能为空")
          private String recipientDistrict;
          ...
      

      (3)Controller层使用@Valid或者@Validated

       @PostMapping("/add")
       public UniformResultTemplate&lt;Boolean&gt; addAddress(@RequestBody @Validated AddressReqDto reqDto, HttpServletRequest request){
         return null;
       }
      

      注意:Post请求方式区别,Get@Validated注解需要加在 所在方法类前

      @RestController
      @RequestMapping("/api/address")
      @Validated
      public class AddressController extends BaseController{
        @ApiOperation("收获地址详情")
          @GetMapping("/detail")
          public UniformResultTemplate<AddressDetailRespDto> queryAddressList(@NotNull(message = "地址Id不能为空") 
      @RequestParam(value = "addressId") Long addressId, HttpServletRequest request){
              return null;
          }
      }

      (4)使用@ControllerAdvice统一异常处理返回。

      @Component
      @ControllerAdvice
      @Slf4j
      public class GlobalExceptionHandler {
          // Post请求Bean中的校验抛出:MethodArgumentNotValidException
          @ExceptionHandler(MethodArgumentNotValidException.class)
          @ResponseBody
          public UniformResultTemplate handleBindException(MethodArgumentNotValidException ex) {
              FieldError fieldError = ex.getBindingResult().getFieldError();
              log.warn("参数校验异常:{}({})", fieldError.getDefaultMessage(),fieldError.getField());
              return new UniformResultTemplate("10002",fieldError.getDefaultMessage());
          }
        // Get请求的参数校验,抛出的是ConstraintViolationException
        @ExceptionHandler(ConstraintViolationException.class)
          @ResponseBody
          public UniformResultTemplate handleGetBindException(ConstraintViolationException ex) {
              Set<ConstraintViolation<?>>  eSet = ex.getConstraintViolations();
              StringBuffer sb = new StringBuffer();
              if(!CollectionUtils.isEmpty(eSet)) {
                  Iterator<ConstraintViolation<?>> iterator = eSet.iterator();
                  while (iterator.hasNext()) {
                      log.warn("参数校验异常:{}({})", iterator.next().getMessage());
                      sb.append(iterator.next().getMessage()).append("::");
                  }
              }
              return new UniformResultTemplate("10002",sb.toString());
          }
        // 方法签名参数错误
          @ExceptionHandler(MissingServletRequestParameterException.class)
          @ResponseBody
          public UniformResultTemplate handleGetBindException(MissingServletRequestParameterException ex) {
              log.warn("参数校验异常:{}", ex.getMessage());
              return new UniformResultTemplate("10002",ex.getMessage());
          }
      }

      (5)结果现象

      {
          &quot;code": "10002",
          "message": "市不能为空",
          "result": null,
          "totalTimes": null,
          "interfaceTimes": null
      }

      4、编译器校验工具

      防止因使用错误Hibernate-Validation注解而导致程序运行时报错,增加编译器校验工具,进行友好提示。

      <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-validator-annotation-processor</artifactId>
          <version>6.1.5.Final</version>
      </dependency>

      以上就是springboot中使用Hibernate-Validation校验参数详解的详细内容,更多关于springboot Hibernate-Validation的资料请关注3672js教程其它相关文章!

      您可能感兴趣的文章:
      • springboot使用hibernate validation对参数校验的实现方法
      • JAVA中通过Hibernate-Validation进行参数验证
      • Hibernate Validation自定义注解校验的实现
      • 如何自定义hibernate validation注解示例代码
      相关栏目:

      用户点评