2.3.1 声明验证规则
对于 Taco 类,希望确保 name 属性不是空的或 null 的,并且所选配料列表中至少有一项。下面的程序清单显示了一个更新后的 Taco 类,它使用 @NotNull
和 @Size
来声明这些验证规则。
程序清单 2.11 为 Taco 域类添加验证
package tacos;
import java.util.List;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import lombok.Data;
@Data
public class Taco {
@NotNull
@Size(min=5, message="Name must be at least 5 characters long")
private String name;
@NotNull
@Size(min=1, message="You must choose at least 1 ingredient")
private List<Ingredient> ingredients;
}
您会发现,除了要求 name 属性不为 null,同时您声明它应该有一个值是至少 5 个字符的长度。
当涉及到对提交玉米饼订单进行验证声明时,必须对 Order 类应用注解。对于地址的属性,只需要确保用户没有留下任何空白字段。对于这一点,将使用 Hibernate Validator 的 @NotBlank
注解。
支付领域的验证是一个比较奇特的存在。您不仅需要确保 ccNumber 属性不为空,还要确保它包含的是一个有效的信用卡号码的值。该 ccExpiration 属性必须符合 MM/YY(两位数的年/月)格式。而 ccCVV 属性必须是一个三位的数字。为了实现这种验证,需要使用一些其他的 Java Bean Validation API 注解,同时需要从 Hibernate Validator 集合中借用一些验证注解。下面程序清单列出了验证 TacoOrder 类所需要的改变。
程序清单 2.12 验证 Order 属性字段
package tacos;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import org.hibernate.validator.constraints.CreditCardNumber;
import java.util.List;
import java.util.ArrayList;
import lombok.Data;
@Data
public class TacoOrder {
@NotBlank(message="Delivery name is required")
private String deliveryName;
@NotBlank(message="Street is required")
private String deliveryStreet;
@NotBlank(message="City is required")
private String deliveryCity;
@NotBlank(message="State is required")
private String deliveryState;
@NotBlank(message="Zip code is required")
private String deliveryZip;
@CreditCardNumber(message="Not a valid credit card number")
private String ccNumber;
@Pattern(regexp="^(0[1-9]|1[0-2])([\\/])([1-9][0-9])$",
message="Must be formatted MM/YY")
private String ccExpiration;
@Digits(integer=3, fraction=0, message="Invalid CVV")
private String ccCVV;
private List<Taco> tacos = new ArrayList<>();
public void addTaco(Taco taco) {
this.tacos.add(taco);
}
}
可以看到,ccNumber 属性用 @CreditCardNumber 进行了注解。该注解声明属性的值必须是通过 Luhn 算法(https://en.wikipedia.org/wiki/Luhn_algorithm)检查过的有效信用卡号。这可以防止用户出错的数据和故意错误的数据,但不能保证信用卡号码实际上被分配到一个帐户,或该帐户可以用于交易。
不幸的是,没有现成的注解来验证 ccExpiration 属性的 MM/YY 格式。我已经应用了 @Pattern 注解,为它提供了一个正则表达式,以确保属性值符合所需的格式。如果想知道如何破译正则表达式,我建议查看许多在线正则表达式指南,包括 http://www.regularexpressions.info/。正则表达式语法是一门黑暗的艺术,当然也超出了本书的范围。
最后,用 @Digits
注解 ccCVV 属性,以确保值恰好包含三个数字。
所有的验证注解都包含一个消息属性,该属性定义了如果用户输入的信息不符合声明的验证规则的要求时将显示给用户的消息。