验证用户的输入来维护数据的完整性是应用程序逻辑的重要部分。在最简单的应用程序中,验证可可以发生在不同的层,如在前面的章节中的guessnumber例子程序中显示的那样。在那个例子程序中,应用程序在表现层验证用户输入的是数字(h:inputText标签),在业务层验证用户输入是否在有效的范围内。
JavaBean验证(bean验证)是一个新的验证模型,是Java EE 6的一部分。通过以annotation的形式给如后台bean这样的JavaBean组件的字段、方法或类添加约束来支持bean验证模型。约束可以是内建的或用户定义的。用户定义的约束叫做客户约束。一些内建的约束位于javax.validation.constraints包中。下表列出了所有的内建的约束。
约束 | 描述 | 例子 |
@AssertFalse | 字段或属性的值必须是false | @AssertFalse boolean isUnsupported; |
@AssertTrue | 字段或属性的值必须是true | @AssertTrue boolean isActive; |
@DecimalMax | 字段或属性的值必须是decimal,并且小于或等于约束中给出的值 | @DecimalMax(“30.00”) BigDecimal discount; |
@DecimalMin | 字段或属性的值必须是decimal,并且大于或等于约束中给出的值 | @DecimalMin(“5.00”) BigDecimal discount; |
@Digits | 字段或属性的值必须是指定范围内的数字。元素integer指定了数字的最大的整数位数,fraction元素指定了最大的小数位数 | @Digits(integer=6, fraction=2) BigDecimal price; |
@Future | 字段或属性的值必须是未来的日期 | @Future Date eventDate; |
@Max | 字段或属性的值必须是小于或等于指定值的整数 | @Max(10) int quantity; |
@Min | 字段或属性的值必须是大于或等于指定值的整数 | @Min(5) int quantity; |
@NotNull | 字段或属性的值必须非空 | @NotNull String userName; |
@Null | 字段或属性的值必须为null | @Null String unusedString; |
@Past | 字段或属性的值必须是过去的日期 | @Past Date birthday; |
@Pattern | 字段或属性的值必须符合regexp元素定义的正则表达式 | @Pattern(regexp=”\\(\\d{3}\\)d{3}-\\d{4}”) String phoneNumber; |
@Size | 字段或属性的size必须在指定的范围内。如果字段或属性是String类型,那么size指的是字符串的size;如果字段或属性是Collection,size指的是Collection的size;如果字段或属性是Map,size指的是Map的size。如果字段或属性是数组,size指的是数组的length。可以使用max或min元素中的一个或两个来自是范围。 | @Size(min=2, max=240) String briefMessage; |
在下面的例子中,使用了内建的@NotNull约束:
- public class Name {
- @NotNull
- private String firstname;
- @NotNull
- private String lastname;
- }
也可以将多个约束放在同一个字段或属性上,如下例所示:
- public class Name {
- @NotNull
- @Size(min=1, max=16)
- private String firstname;
- @NotNull
- @Size(min=1, max=16)
- private String lastname;
- }
下面的例子显示了怎样在一个方法上使用一个用户定义的约束来检查预先定义的email地址模式:
- @ValidEmail
- public String getEmailAddress() {
- return emailAddress;
- }
对于内建的约束,都有有效的默认的实现。对于用户定义的约束(客户约束)则需要相应的实现类。上面例子中的@ValidEmail用户约束就需要相应的实现类。
任何验证失败都会被优雅的处理并能够被h:messages标签显示。任何包含Bean验证组件的后台bean都会自动的得到放在JavaServer Faces应用程序的web页面的字段上的约束。
更多关于使用验证约束的信息见“验证持久化的字段和属性”一节。
验证null字符串和空字符串
Java编程语言会区分null和空字符串。空字符串是一个长度为0的字符串实例。null字符串表示根本没有任何值。
空字符串用""表示。是一个包含0个字符的字符数组。null字符串用null表示。null字符串表示没有字符串实例。
表示为JavaServer Faces文本组件(如inputText)的后台bean的元素会被JavaServer Faces实现使用空字符串初始化。
验证不强制用户输入的字段会是一个问题。看看下面的例子,当testString是一个bean的变量,会使用用户的输入来设置该变量,并且用户对这个字段的输入并不是强制的:
- if (testString.equals(null)) {
- doSomething();
- } else {
- doAnotherThing();
- }
默认情况下,即使用户没有输入任何值,doAnotherThing方法仍然会被调用,因为testString元素被初始化为空字符串。
要使Bean验证模型按照我们设想的工作,必须在web布署描述符(web.xml)中将环境参数
- javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL设置为true:
- <context-param>
- <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
- <param-value>true</param-value>
- </context-param>
这个参数使得JavaServer Faces实现将空字符串作为null对待。假设在另一个地方有一个@NotNull约束,表明必须要有用户输入。在这种情况下,空字符串会通过验证。但是如果将这个环境参数设置为true了,那么运行时传递给bean验证的后台bean的属性就是null值,会导致通不过验证。