javaBean验证框架(5)—自定义类级别约束
我们前面看到验证注解可以在属性上使用,但有时我们需要在多个属性之间进行验证,即类级别的验证。
文本介绍如何定义类级别的验证。
定义注解
和之前定义的注解几乎一样,但有点区别,看这句代码
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
,较之之前的定义多了ElementType.TYPE
,表示该注解只能应用在类或接口上。其他的内容几乎一致,不再缀述。
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = OrderValidator.class)
@Documented
public @interface AOrder {
String message () default "total price must be 50 or greater for online order. " +
"Found: ${validatedValue.totalPrice}";
Class<?>[] groups () default {};
Class<? extends Payload>[] payload () default {};
}
实现类级别验证器
验证器实现验证逻辑,本示例中,需要订单的金额(数量*单价)需大于或等于50.看下面代码:
import com.dataz.entity.Order;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.math.BigDecimal;
public class OrderValidator implements
ConstraintValidator<AOrder, Order> {
@Override
public void initialize (AOrder constraintAnnotation) {
}
@Override
public boolean isValid (Order order,
ConstraintValidatorContext context) {
if (order.getPrice() == null || order.getQuantity() == null) {
return false;
}
return order.getTotalPrice()
.compareTo(new BigDecimal(50)) >= 0;
}
}
定义实体并验证
这里首先定义被验证类Order,并进行验证。
Order类:
这里在类上使用了我们定义的注解:
@AOrder
。
import com.dataz.validate.AOrder;
import java.math.BigDecimal;
import java.math.RoundingMode;
@AOrder
public class Order {
private final BigDecimal price;
private final BigDecimal quantity;
public Order (BigDecimal price, BigDecimal quantity) {
this.price = price;
this.quantity = quantity;
}
public BigDecimal getPrice () {
return price;
}
public BigDecimal getQuantity () {
return quantity;
}
public BigDecimal getTotalPrice () {
return (price != null && quantity != null ?
price.multiply(quantity) : BigDecimal.ZERO)
.setScale(2, RoundingMode.CEILING);
}
}
验证Order类对象
下面代码片段,进行验证,完整代码看github中的
ValidationDemo3
类。
public static void OrderClassLevelValidate(){
Order order = new Order(new BigDecimal(4.5), new BigDecimal(9));
Set<ConstraintViolation<Order>> constraintViolations =
validator.validate(order);
if (constraintViolations.size() > 0) {
constraintViolations.stream().forEach(
ValidationDemo3::printError);
} else {
//proceed using order
System.out.println(order);
}
}
输出结果为:total price must be 50 or greater for online order. Found: 40.50
。
总结
本文介绍如何定义类级别验证,仅需要在注解申明中加入
ElementType.TYPE
,指明在类或接口上使用,然后实现相应逻辑即可,简洁明了。