Bean Validation (JSR 303/349) 是 Java 參數校驗的標準化方案,Hibernate Validator 是其參考實現。本文以 Maven 專案為例,從依賴引入、實體類註解、驗證器啟動到 JUnit 單元測試,完整演示一個「汽車資料校驗」案例。
<dependencies>
<!-- Hibernate Validator 核心 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.3.2.Final</version>
</dependency>
<!-- JUnit 測試 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
提示:4.3.x 版本需 JDK 6+,若使用 Spring Boot 2.x+ 建議升級至 6.x 版本(對應 JSR 380)。
package po;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class Car {
@NotNull(message = "製造商不能為空")
private String manufacturer;
@NotNull
@Size(min = 2, max = 14, message = "車牌長度需在 2-14 字元")
private String licensePlate;
@Min(value = 2, message = "座位數至少 2 個")
private int seatCount;
public Car(String manufacturer, String licensePlate, int seatCount) {
this.manufacturer = manufacturer;
this.licensePlate = licensePlate;
this.seatCount = seatCount;
}
// 省略 getter/setter
}
| 註解 | 適用類型 | 說明 |
|---|---|---|
| @NotNull | 任意 | 值不為 null |
| @Size | String, Collection, Map, Array | 長度/大小範圍 |
| @Min/@Max | 數值類型 | 最小/最大值 |
| @Pattern | String | 正則匹配 |
| String | 郵箱格式(HV 專屬) |
package test;
import org.junit.BeforeClass;
import org.junit.Test;
import po.Car;
import javax.validation.*;
import java.util.Set;
public class CarTest {
private static Validator validator;
@BeforeClass
public static void setUp() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator(); // 線程安全,可複用
}
@Test
public void testManufacturerNull() {
Car car = new Car(null, "DD-AB-123", 4);
Set<ConstraintViolation<Car>> violations = validator.validate(car);
System.out.println("違規數:" + violations.size());
violations.forEach(v -> System.out.println(v.getPropertyPath() + " " + v.getMessage()));
// 輸出:manufacturer 製造商不能為空
}
@Test
public void testLicensePlateTooShort() {
Car car = new Car("Morris", "D", 4);
Set<ConstraintViolation<Car>> violations = validator.validate(car);
// 輸出:licensePlate 車牌長度需在 2-14 字元
}
@Test
public void testSeatCountTooLow() {
Car car = new Car("Morris", "DD-AB-123", 1);
Set<ConstraintViolation<Car>> violations = validator.validate(car);
// 輸出:seatCount 座位數至少 2 個
}
@Test
public void testValidCar() {
Car car = new Car("Morris", "DD-AB-123", 2);
Set<ConstraintViolation<Car>> violations = validator.validate(car);
assert violations.isEmpty(); // 通過
}
}
Validation (入口)
↓ buildDefaultValidatorFactory()
ValidatorFactory (工廠,線程安全)
↓ getValidator()
Validator (核心介面,線程安全)
↓ validate(object)
Set> (違規詳情集合)
每個 ConstraintViolation 包含:
- propertyPath: 屬性路徑
- message: 違規描述
- messageTemplate: 模板
- rootBeanClass: 根對象類型
@NotNull(groups = UpdateGroup.class)`,`validator.validate(car, UpdateGroup.class)`。@Valid` 遞歸校驗。ConstraintValidator` 定義業務規則(如身分證校驗)。@Valid` + `BindingResult` 自動綁定錯誤。Hibernate Validator 以註解聲明式校驗替代大量 `if-else` 判斷,配合 JSR 標準 API,實現「寫一次註解、多層複用(Service/Controller/前端)」的優雅校驗架構。掌握 `Validator`、`ConstraintViolation` 核心流程,即可快速落地業務參數檢查。