案例概述
在這本文中,我們將介紹使用標準框架驗證Java bean的基礎知識 - JSR 380,也稱為Bean Validation 2.0。
當然,驗證使用者輸入在大多數應用程式中是一個超常見的要求,Java Bean Validation框架已經成為處理這種邏輯的事實上的標準。
JSR 380
JSR 380是用於bean驗證的Java API的規範,是JavaEE和JavaSE的一部分,它使用@NotNull、@Min和@Max等註釋確保bean的屬性滿足特定的標準。
此版本需要Java 8或更高版本,並利用Java 8中新增的新功能(如型別註釋),並支援Optional和LocalDate等新型別。
有關規範的完整資訊,請繼續閱讀JSR 380。
依賴性
我們將使用Maven示例來顯示所需的依賴項,但當然,可以使用各種方式新增這些jar。
驗證API
根據JSR 380規範,validation-api依賴包含標準驗證API:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.0.Final</version>
</dependency>
驗證API參考實現
Hibernate Validator是驗證API的參考實現。
要使用它,我們必須新增以下依賴項:
<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的永續性方面,並且透過將其新增為依賴項,我們不會將這些永續性方面新增到專案中。
表示式語言依賴關係
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.ExpressionFactory'。檢查您是否在類路徑上有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驗證的基礎知識。