Java Bean Validation可以在Java Bean的屬性掛上注釋(Annotation)來進行驗證。
例如有一個Customer
Java Bean,有一個屬性custId
的長度必須為10,所以我們可以自訂一個annotation @CustIdLength
來進行驗證。
使用前要匯入Java Validation API的jar,以及其實作Hibernate Validator的jar。這裡使用Maven的pom.xml
。
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>5.2.4.Final</version>
</dependency>
Customer.java
package idv.matt.model;
import javax.validation.constraints.NotNull;
import idv.matt.annotation.CustIdLength;
public class Customer {
@CustIdLength // 自訂的annotation
private String custId;
@NotNull // Java Bean Validation的annotation
private String custName;
// getter and setter ommitted
}
@CustIdLength
package idv.matt.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.ReportAsSingleViolation;
import idv.matt.annotation.validator.CustIdLengthValidator;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Constraint(validatedBy = { CustIdLengthValidator.class })
@ReportAsSingleViolation
public @interface CustIdLength {
String message() default "custId length should be 10";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
CustIdLengthValidator.java
package idv.matt.annotation.validator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import idv.matt.annotation.CustIdLength;
public class CustIdLengthValidator implements ConstraintValidator<CustIdLength, String> {
@Override
public void initialize(CustIdLength constraintAnnotation) {
}
@Override
public boolean isValid(String custId, ConstraintValidatorContext ctx) {
if (custId == null) {
return true; // 通過
}
if (custId.length() == 10) {
return true; // 通過
}
return false; // 不通過
}
}
測試
package idv.matt.main;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import idv.matt.model.Customer;
public class Main {
public static void main(String[] args) {
ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
Validator validator = vf.getValidator();
Customer customer = new Customer();
customer.setCustId("1234567890XX");
validate(validator, customer);
vf.close();
}
private static void validate(Validator validator, Customer customer) {
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
if (violations.isEmpty()) {
System.out.println("Valid customer: " + customer.getCustId());
} else {
for (ConstraintViolation<Customer> violation : violations) {
System.out.println(violation.getMessage());
}
throw new ConstraintViolationException(violations);
}
}
}
執行後訊息如下
custId length should be 10
may not be null
Exception in thread "main" javax.validation.ConstraintViolationException: custId: custId length should be 10, custName: may not be null
at idv.matt.main.Main.validate(Main.java:xx)
at idv.matt.main.Main.main(Main.java:xx)
後來發現不用那麼麻煩自己寫Validator,改用@Size(max=10, min=10)
即可。
package idv.matt.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.ReportAsSingleViolation;
import javax.validation.constraints.Size;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Constraint(validatedBy = {})
@Size(max=10, min=10)
@ReportAsSingleViolation
public @interface CustIdLength {
String message() default "custId length should be 10";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
參考:
- Java Bean Validation example
- Java Bean Validation Basics
- Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath
- Create Your Own Constraints With Bean Validation 2.0
- Spring Boot 自訂Controller請求參數Bean Validation
沒有留言:
張貼留言