本文介绍了声明Bean的约束的四种类型,并分别举例,展示代码,简单说明四种Bean的约束。

一、声明Bean的约束

Bean Validation中的约束通过java注解被表达。在这部分中,你将学到如何强化一个对象模型通过这些注解。这有四种类型的bean约束:

  • 成员变量约束。
  • 属性约束。
  • 容器元素约束。
  • 类约束。

不是所有的约束都可以放在所有这些级别上。事实上,没有定义在Bean Validation中的默认的约束,可以放在类级别上。

这个“java.lang.annotation.Target”注解在约束注解中,它自身决定关于每个元素注解可以放的地方,可以看后续的“自定义注解”。

1.1 成员变量级别的约束

约束可以通过注解一个类的成员变量来表达。例子:2.1“成员变量级别的约束”展示了一个成员变量级别的配置例子。

例2.1:成员变量约束

图片说明

当使用成员变量级别的约束,也就是域访问策略的值需要被验证。这意味着这个验证引擎可以直接访问实例变量,即使存在一个访问器,也不会调用属性访问器方法。

约束可以被应用在任何访问类型(public,private,etc)的成员变量上,但是在static fields上的约束目前不支持。

当验证字节码强化对象的时候,属性级别的约束应该被使用,因为字节码强化库不能通过反射决定一个域的访问。

1.2 Property-level 约束

如果你的模型类遵循javabean的标准,它也可能注解这个bean的属性而不是它的成员变量。

例2.2 “Property-level 约束”使用了和例2.1相同的实体。然而,Property-level的约束可以使用。
图片说明

这个属性的getter方法必须被注解,而不是它的setter方法。这种方式只读的属性(没有setter方法)可以被约束。

当使用属性约束访问策略的时候,对应访问的值是需要被验证的。这个验证引擎通过属性访问器方法,可以直接访问它的状态。

推荐在一个类中严格地只使用域或是属性注解中的一种。不推荐即使用一个域注解,又同时使用getter方法,这会导致这个域被验证两次。

1.3 容器元素约束

直接指定约束在类型参数上面的参数类型上面是可能的:这些约束被调用容器元素约束。

这个需要通过@Target注解在约束定义中指定ElementType.TYPE_USE。

由于BeanValidation2.0,被内建的Bean Validation同时也是Hibernate Validator指定的约束,指定Element.TYPE_USE,可以直接用在这个环境中:

  • java.util.Iterable(e.g.Lists, Sets)的实现。
  • java.util.Map的实现,同时指出key和value。
  • java.util.Optional;
  • java.util.OptionalInt;
  • java.util.OptionalDouble;
  • java.util.OptionalLong.

还有许多JavaFX(javafx.bean.observable.ObservableValue)的实现。也支持自定义的容器类型。我们接下来展示一些例子,来阐述在各种java类型上的容器元素约束。在这些例子中,@ValidPart是一个自定义的约束,被允许用在TYPE_USE环境中。

1.4 类级别约束

一个约束考科一被放到类级别上,在这种情况下,被验证的对象不是简单的一个属性,而是一个完整的对象。如果类级别约束,验证的是几个属性之间的相关性,则类级别属性是很有用的。

在例2.9“类级别的约束”中的Car类有两个属性seatCount和passengers,它应该确定这个passengers List不应该有超过可用seats的实体的数量。

为了这个目的,这个@ValidPassengerCount约束被加载类级别上。这个约束的验证器可以访问这个完整的Car对象,并允许比较seats和passengers的数量。

下图是类级别的约束,也就是在类上的那个注解。

图片说明