Java Bean Validation

案例概述

在這本文中,咱們將介紹使用標準框架驗證Java bean的基礎知識 - JSR 380,也稱爲Bean Validation 2.0。java

固然,驗證用戶輸入在大多數應用程序中是一個超常見的要求,Java Bean Validation框架已經成爲處理這種邏輯的事實上的標準。web

JSR 380

JSR 380是用於bean驗證的Java API的規範,是JavaEE和JavaSE的一部分,它使用@NotNull、@Min和@Max等註釋確保bean的屬性知足特定的標準。編程

此版本須要Java 8或更高版本,並利用Java 8中添加的新功能(如類型註釋),並支持Optional和LocalDate等新類型。api

有關規範的完整信息,請繼續閱讀JSR 380數組

依賴性

咱們將使用Maven示例來顯示所需的依賴項,但固然,可使用各類方式添加這些jar。框架

驗證API

根據JSR 380規範,validation-api依賴包含標準驗證API:less

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.0.Final</version>
</dependency>
驗證API參考實現

Hibernate Validator是驗證API的參考實現。ui

要使用它,咱們必須添加如下依賴項:hibernate

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

這裏快速說明的是,hibernate-validator徹底獨立於Hibernate的持久性方面,而且經過將其添加爲依賴項,咱們不會將這些持久性方面添加到項目中。code

表達式語言依賴關係

JSR 380提供對變量插值的支持,容許在違規消息中使用表達式。

要解析這些表達式,咱們必須在表達式語言API和該API的實現上添加依賴項。GlassFish提供參考實現:

<dependency>
    <groupId>javax.el</groupId>
    <artifactId>javax.el-api</artifactId>
    <version>3.0.0</version>
</dependency>
 
<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>javax.el</artifactId>
    <version>2.2.6</version>
</dependency>

若是未添加這些JAR,您將在運行時收到錯誤消息,以下所示:

HV000183:沒法加載'javax.el.E​​xpressionFactory'。檢查您是否在類路徑上有EL依賴項,或使用ParameterMessageInterpolator

使用驗證註釋

咱們將在這裏使用User bean做爲主要示例,併爲其添加一些簡單的驗證:

import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.validation.constraints.Email;
 
public class User {
 
    @NotNull(message = "Name cannot be null")
    private String name;
 
    @AssertTrue
    private boolean working;
 
    @Size(min = 10, max = 200, message 
      = "About Me must be between 10 and 200 characters")
    private String aboutMe;
 
    @Min(value = 18, message = "Age should not be less than 18")
    @Max(value = 150, message = "Age should not be greater than 150")
    private int age;
 
    @Email(message = "Email should be valid")
    private String email;
 
    // standard setters and getters 
}

示例中使用的全部註釋都是標準的JSR註釋:

  • @NotNull - 驗證帶註釋的屬性值不爲 null
  • @AssertTrue - 驗證帶註釋的屬性值是否爲 true
  • @Size - 驗證帶註釋的屬性值是否具備屬性min和max之間的大小; 能夠應用於String, Collection, Map和數組屬性
  • @Min - 驗證帶註釋的屬性的值是否小於value屬性
  • @Max - 驗證帶註釋的屬性的值是否大於value屬性
  • @Email - 驗證帶註釋的屬性是否爲有效的電子郵件地址

某些註釋接受其餘屬性,但message屬性對全部屬性都是通用的。這是當相應屬性的值未經過驗證時一般會呈現的消息。

能夠在JSR中找到的一些其餘註釋是:

  • @NotEmpty - 驗證屬性不爲null或爲空; 能夠應用於String, Collection, Map或 Array值
  • @NotBlank - 只能應用於文本值,並驗證該屬性不是null或空格
  • @Positive和@PositiveOrZero - 適用於數值並驗證它們是嚴格正數仍是正數,包括0
  • @Negative和@NegativeOrZero - 適用於數值並驗證它們是嚴格爲負數,仍是負數,包括0
  • @Past和@PastOrPresent - 驗證日期值是否過去,包括如今; 能夠應用於日期類型,包括Java 8中添加的日期類型
  • @Future和@FutureOrPresent - 驗證日期值是否未來包括如今

驗證註釋也能夠應用於集合的元素:

List<@NotBlank String> preferences;

在這種狀況下,將驗證添加到選項列表中的任何值。

該規範還支持 Java 8中的新Optional類型:

private LocalDate dateOfBirth;
 
public Optional<@Past LocalDate> getDateOfBirth() {
    return Optional.of(dateOfBirth);
}

在這裏,驗證框架將自動解包LocalDate值並對其進行驗證。

程序驗證

一些框架 - 例如Spring--只需使用註釋就能夠經過簡單的方法觸發驗證過程。這主要是爲了使咱們沒必要與程序驗證API進行交互。

如今讓咱們進入手動路線並以編程方式設置:

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();

要驗證bean,咱們必須首先擁有Validator對象,該對象使用ValidatorFactory構造。

定義Bean

咱們如今要設置一個無效用戶 - 使用空名稱值:

User user = new User();
user.setWorking(true);
user.setAboutMe("Its all about me!");
user.setAge(50);
驗證Bean

如今咱們有了一個Validator,咱們能夠經過將它傳遞給validate方法來驗證咱們的bean 。任何違反User對象中定義的約束的行爲都將做爲Set返回。

Set<ConstraintViolation<User>> violations = validator.validate(user);

經過迭代違規,咱們可使用getMessage方法獲取全部違規消息。

for (ConstraintViolation<User> violation : violations) {
    log.error(violation.getMessage()); 
}

在咱們的示例中(ifNameIsNull_nameValidationFails),該集合將包含一個ConstraintViolation,消息「 Name not not null」。

案例結論

本文重點介紹了標準Java Validation API的簡單傳遞,並使用javax.validation註釋和API 說明了bean驗證的基礎知識。

相關文章
相關標籤/搜索