hibernate validate 后台入参校验

一、Hibernate-Validator简介

在RESTful 风格的接口服务中,会有各种各样的入参,我们不可能完全不做任何校验就直接进入到业务处理的环节,因此在前期我们会有一个基础的数据验证的机制,待这些验证通过后,参数才会进入到正式的业务处理环节。
数据验证又分为两种:
(1)一种是无业务关联的规则性验证;
(2)一种是根据现有数据进行的联动性数据验证(简单来说,参数的合理性需要查数据库)。
Hibernate-Validator 是一种校验机制,比较适合做无业务关联的规则性验证。
官网:http://hibernate.org/validator/releases/6.0/

在使用时需要在pom中引入依赖,如下所示:

<!-- hibernate校验依赖 -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.15.Final</version>
</dependency>

二、JSR 303和JSR 349

简单来说,就是Java规定了一套关于验证器的接口。开始的版本是Bean Validation 1.0(JSR-303),然后是Bean Validation 1.1(JSR-349),目前最新版本是Bean Validation 2.0(JSR-380),官网入口:https://beanvalidation.org/2.0/

从上可以看出Bean Validation并不是一项技术而是一种规范,需要对其实现。hibernate团队提供了参考实现,Hibernate validator 5是Bean Validation 1.1的实现,Hibernate Validator 6.0是Bean Validation 2.0规范的参考实现。新特性可以到官网查看。对于方法参数/返回值验证,大家可以参阅《hibernate官方文档)

如果项目的框架是spring boot的话,在依赖spring-boot-starter-web中已经包含了Hibernate-validator的依赖。Hibernate-Validator的主要使用的方式就是注解的形式,并且是“零配置”的,也就是说无需配置也可以使用。


三、Hibernate-Validator内置的校验注解

首先列举一下Hibernate-Validator所有的内置验证注解。

常用的校验注解如下表所示:

注解 说明
@NotNull 被注释的元素(任何元素)必须不为null,但集合为空也是可以的。没啥实际意义
@NotEmpty 用来校验字符串、集合、map、数组不能为null或空 (字符串传入空格也不可以)(集合需至少包含一个元素)功能强于@NotNull
@NotBlank 只用来校验字符串不为null,不为空值,不为全空格。功能强大于@NotEmpty
@Size(max=, min=) 指定的字符串、集合、map、数组长度必须在指定的max和min范围内。(允许元素为null,字符串允许为空格)
@Length(min=,max=) 只用来校验字符串,长度必须在指定的max和min范围内。(允许元素为null)
@Range(min=,max=) 用来校验数字或字符串的大小必须在指定的min和max范围内,字符串会转成数字进行比较,如果不是数字校验不通过。(允许元素为null)
@Min() 校验数字(包括integer、short、long、int等)的最小值,不支持小数即double和float。(允许元素为null)
@Max() 校验数字(包括integer、short、long、int等)的最大值,不支持小数即double和float。(允许元素为null)
@Pattern() 正则表达式匹配,可用来校验年月日格式是否包含特殊字符
@Valid 递归的对关联对象进行校验,如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验

主要区分下@NotNull、@NotEmpty、@NotBlank 3个注解的区别:
(1)@NotNull:任何对象的value不能为null。
(2)@NotEmpty:集合对象的元素不为0,即集合不为空,也可以用于字符串不为null。
(3)@NotBlank:只能用于字符串不为null,并且字符串trim()以后length要大于0。

需要注意如下几点:
(1)除了@Empty要求字符串不能全是空格,其他的字符串校验都是允许空格的。
(2)message是可以引用常量的,但是如@Size里max不允许引用对象常量,基本类型常量是可以的。message是错误提示信息,是可以返回给前台的。
(3)大部分规则校验都是允许参数为null,即当不存在这个值时,就不进行校验了。


不太常用的校验注解如下表所示:

注解 说明
@Null 被注释的元素必须为null
@AssertTrue 被注释的元素必须为true
@AssertFalse 被注释的元素必须为false
@DecimalMin(value=,message=) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value=,message=) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Email 被注释的元素必须是电子邮箱地址

四、实际使用

使用Hibernate Validator做简单检验时,使用注解即可,需要引入Hibernate Validator包。只需要在bean写上具体校验注解,controller层入参加上@Validated注解,接口入参上加上@Validated注解即可。

如下所示:

@RequestMapping(value = "/addgoods")
public Results addGoods(@Validated @RequestBody GoodsAddDTO goodsAddDTO, BindingResult result) {
    // 在校验过程中如果发生校验不成功的情况,则需要收集失败信息,以返回给用户
     if (result.hasErrors()) {
            return Results.error(-1, result.getFieldError().getDefaultMessage());
        }
    // 调用service层并返回结果
}

接口层如下:

Results savaGoods(@Valid GoodsAddDTO goodsAddDTO);

bean如下:

public class GmsGoodsBasicInfo implements Serializable {
    private static final long serialVersionUID = 1L;

    private Integer id;

    @NotEmpty(message = "商品编号不能为空")
    @Length(min = 1, max = 10, message = "商品编号长度在1到10之间")
    private String goodsCode;
    
    //setter/getter
}

参考博文:
(1)https://blog.csdn.net/java_collect/article/details/85534054
(2)https://blog.csdn.net/xgblog/article/details/52548659
(3)https://blog.csdn.net/danielzhou888/article/details/74740817
(4)https://www.jianshu.com/p/2c958b377dd2
(5) https://blog.csdn.net/ye___li/article/details/107512099 (复杂校验,list,嵌套对象校验等)
(6) https://blog.csdn.net/jinzhencs/article/details/51682830
(7) https://juejin.im/post/6844903929331843086 (基本用法,和返回校验出错结果,嵌套校验等)

posted @ 2020-09-16 16:31  jason小蜗牛  阅读(616)  评论(0编辑  收藏  举报