1. 程式人生 > 實用技巧 >hibernate validate 後臺入參校驗

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 (基本用法,和返回校驗出錯結果,巢狀校驗等)