Java Bean Validation

13次阅读

共计 3843 个字符,预计需要花费 10 分钟才能阅读完成。

案例概述
在这本文中,我们将介绍使用标准框架验证 Java bean 的基础知识 – JSR 380,也称为 Bean Validation 2.0。
当然,验证用户输入在大多数应用程序中是一个超常见的要求,Java Bean Validation 框架已经成为处理这种逻辑的事实上的标准。
JSR 380
JSR 380 是用于 bean 验证的 Java API 的规范,是 JavaEE 和 JavaSE 的一部分,它使用 @NotNull、@Min 和 @Max 等注释确保 bean 的属性满足特定的标准。
此版本需要 Java 8 或更高版本,并利用 Java 8 中添加的新功能(如类型注释),并支持 Optional 和 LocalDate 等新类型。
有关规范的完整信息,请继续阅读 JSR 380。
依赖性
我们将使用 Maven 示例来显示所需的依赖项,但当然,可以使用各种方式添加这些 jar。
验证 API
根据 JSR 380 规范,validation-api 依赖包含标准验证 API:
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.0.Final</version>
</dependency>
验证 API 参考实现
Hibernate Validator 是验证 API 的参考实现。
要使用它,我们必须添加以下依赖项:
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.2.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator-annotation-processor</artifactId>
    <version>6.0.2.Final</version>
</dependency>
这里快速说明的是,hibernate-validator 完全独立于 Hibernate 的持久性方面,并且通过将其添加为依赖项,我们不会将这些持久性方面添加到项目中。
表达式语言依赖关系
JSR 380 提供对变量插值的支持,允许在违规消息中使用表达式。
要解析这些表达式,我们必须在表达式语言 API 和该 API 的实现上添加依赖项。GlassFish 提供参考实现:
<dependency>
    <groupId>javax.el</groupId>
    <artifactId>javax.el-api</artifactId>
    <version>3.0.0</version>
</dependency>
 
<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>javax.el</artifactId>
    <version>2.2.6</version>
</dependency>
如果未添加这些 JAR,您将在运行时收到错误消息,如下所示:
HV000183:无法加载 ’javax.el.E​​xpressionFactory’。检查您是否在类路径上有 EL 依赖项,或使用 ParameterMessageInterpolator
使用验证注释
我们将在这里使用 User bean 作为主要示例,并为其添加一些简单的验证:
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.validation.constraints.Email;
 
public class User {
 
    @NotNull(message = “Name cannot be null”)
    private String name;
 
    @AssertTrue
    private boolean working;
 
    @Size(min = 10, max = 200, message
      = “About Me must be between 10 and 200 characters”)
    private String aboutMe;
 
    @Min(value = 18, message = “Age should not be less than 18”)
    @Max(value = 150, message = “Age should not be greater than 150”)
    private int age;
 
    @Email(message = “Email should be valid”)
    private String email;
 
    // standard setters and getters
}
示例中使用的所有注释都是标准的 JSR 注释:

@NotNull – 验证带注释的属性值不为 null
@AssertTrue – 验证带注释的属性值是否为 true
@Size – 验证带注释的属性值是否具有属性 min 和 max 之间的大小; 可以应用于 String,Collection,Map 和数组属性
@Min – 验证带注释的属性的值是否小于 value 属性
@Max – 验证带注释的属性的值是否大于 value 属性
@Email – 验证带注释的属性是否为有效的电子邮件地址

某些注释接受其他属性,但 message 属性对所有属性都是通用的。这是当相应属性的值未通过验证时通常会呈现的消息。
可以在 JSR 中找到的一些其他注释是:

@NotEmpty – 验证属性不为 null 或为空; 可以应用于 String,Collection,Map 或 Array 值
@NotBlank – 只能应用于文本值,并验证该属性不是 null 或空格
@Positive 和 @PositiveOrZero – 适用于数值并验证它们是严格正数还是正数,包括 0
@Negative 和 @NegativeOrZero – 适用于数值并验证它们是严格为负数,还是负数,包括 0
@Past 和 @PastOrPresent – 验证日期值是否过去,包括现在; 可以应用于日期类型,包括 Java 8 中添加的日期类型
@Future 和 @FutureOrPresent – 验证日期值是否将来包括现在

验证注释也可以应用于集合的元素:
List<@NotBlank String> preferences;
在这种情况下,将验证添加到选项列表中的任何值。
该规范还支持 Java 8 中的新 Optional 类型:
private LocalDate dateOfBirth;
 
public Optional<@Past LocalDate> getDateOfBirth() {
    return Optional.of(dateOfBirth);
}
在这里,验证框架将自动解包 LocalDate 值并对其进行验证。
程序验证
一些框架 – 例如 Spring– 只需使用注释就可以通过简单的方法触发验证过程。这主要是为了使我们不必与程序验证 API 进行交互。
现在让我们进入手动路线并以编程方式设置:
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
要验证 bean,我们必须首先拥有 Validator 对象,该对象使用 ValidatorFactory 构造。
定义 Bean
我们现在要设置一个无效用户 – 使用空名称值:
User user = new User();
user.setWorking(true);
user.setAboutMe(“Its all about me!”);
user.setAge(50);
验证 Bean
现在我们有了一个 Validator,我们可以通过将它传递给 validate 方法来验证我们的 bean。任何违反 User 对象中定义的约束的行为都将作为 Set 返回。
Set<ConstraintViolation<User>> violations = validator.validate(user);
通过迭代违规,我们可以使用 getMessage 方法获取所有违规消息。
for (ConstraintViolation<User> violation : violations) {
    log.error(violation.getMessage());
}
在我们的示例中(ifNameIsNull_nameValidationFails),该集合将包含一个 ConstraintViolation,消息“Name not not null”。
案例结论
本文重点介绍了标准 Java Validation API 的简单传递,并使用 javax.validation 注释和 API 说明了 bean 验证的基础知识。

正文完
 0