Java_Bean验证基础知识

363 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 9 天,点击查看活动详情

1. 概述

本文中,我们了解一下使用标准框架-JSR380,也被称为Bean Validation 2.0来验证Java bean的基础知识。

在大多数应用程序员,验证用户输入是一个非常普遍的要求。而Java Bean Validation框架已经成为处理这种逻辑的事实上的标准。

2. JSR 380

JSR380是用于bean验证的Java API规范,是Jakarta EE和JavaSE的一部分。这确保了bean的属性满足特定标准,使用诸如@NotNull @Min 和 @Max之类的注解。

此版本需要Java 8或更高版本,并利用Java 8中添加的新功能,例如类型注释和对Optional和LocalDate等新特性的支持。

有关规范的完整信息,请继续阅读JSR 380 - jcp.org/en/jsr/deta…

3. 依赖

本文使用Maven示例来显示所需要的依赖项。当然也可以通过其他方式来添加这些依赖。

3.1. Validation API

根据JSR 380规范,validation-api依赖项是验证Java API规范标准。

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

3.2. Validation API 实现依赖

Hibernate Validator 是Validator API的实现.

要使用它,我们需要添加如下依赖:

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.13.Final</version>
</dependency>

注意:hibernate-validator完全独立于Hirbernate orm的功能,所以即使我们添加了hibernate-validator依赖也没有引入Hibernate ORM的功能。

3.3. 表达式语言依赖

JSR 380支持变量插值,允许在错误信息中使用表达式。

为了解析这些表达式,我们要添加来自GlassFish的依赖项javax.el,其中包含了表达式语言的实现:

<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.el</artifactId>
    <version>3.0.0</version>
</dependency>

4. 使用验证注解

在这里,我们创建一个用户实体类User,并向其添加一些简单的验证:

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 = "姓名不能为空")
    private String name;

    @AssertTrue
    private boolean working;

    @Size(min = 10, max = 200, message 
      = "关于我必须界于10到200字符")
    private String aboutMe;

    @Min(value = 18, message = "年龄不能小于18")
    @Max(value = 150, message = "年龄不能超过150")
    private int age;

    @Email(message = "邮箱必须是有效的")
    private String email;

    // standard setters and getters 
}

示例中使用的所有注解都是标准的JSR注解:

  • @NotNull validates that the annotated property value is not null.
  • @AssertTrue validates that the annotated property value is true.
  • @Size validates that the annotated property value has a size between the attributes min and max; can be applied to String, Collection, Map, and array properties.
  • @Min validates that the annotated property has a value no smaller than the value attribute.
  • @Max validates that the annotated property has a value no larger than the value attribute.
  • @Email validates that the annotated property is a valid email address.

一些注解有额外的属性,但是message属性对所有注解都是能用的。这是相应属性的值未通过验证时通常会返回的消息。

另外在JSR中还有一些附加的注解:

  • @NotEmpty validates that the property is not null or empty; can be applied to String, Collection, Map or Array values.
  • @NotBlank can be applied only to text values and validates that the property is not null or whitespace.
  • @Positive and @PositiveOrZero apply to numeric values and validate that they are strictly positive, or positive including 0.
  • @Negative and @NegativeOrZero apply to numeric values and validate that they are strictly negative, or negative including 0.
  • @Past and @PastOrPresent validate that a date value is in the past or the past including the present; can be applied to date types including those added in Java 8.
  • @Future and @FutureOrPresent validate that a date value is in the future, or in the future including the present.

验证注解同样也可以应用在集合的元素中:

List<@NotBlank String> preferences;

在这种情况下,任何添加到该集合中的元素都会被验证。

Also, the specification supports the new *Optional* type in Java 8:

同样,这个规范支持Java 8中的Optional新特性:

private LocalDate dateOfBirth;

public Optional<@Past LocalDate> getDateOfBirth() {
    return Optional.of(dateOfBirth);
}

在这里,验证框架将自动解包LocalDate值并对其进行验证。

5. 程序验证

某些框架,例如Spring,具有仅使用注解即可触发验证请求参数的简单方法。这主要避免了我们编程验证。

现在让我们来以编程的方式进行验证:

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();

为了验证一个Bean,我们首先需要通过ValidatorFactory来创建一个验证器对象

5.1. 定义Bean

我们现在要创建一个无效的用户,它人名字为空:

User user = new User();
user.setWorking(true);
user.setAboutMe("Its all about me!");
user.setAge(50);

5.2. 验证 Bean

现在我们有了一个验证器,我们可以通过将Bean作为参数传给验证器的validate方法来验证。

任何违返User对象中定义的验证规则都将作为都将作为Set返回:

Set<ConstraintViolation<User>> violations = validator.validate(user);

通过遍历错误信息,我们可以使用getMessage方法获取所有的错误信息:

for (ConstraintViolation<User> violation : violations) {
    log.error(violation.getMessage()); 
}

在我们的示例中,该集合将包含一条信息:"姓名不能为空的"

6. 结论

本文重点介绍如何简单地使用标准Java Validation API。我们展示了使用javax.validation注解和API进行bean验证的基础知识。 你可以在这里看完整的示例代码 gitee - gitee.com/clzbgl/blog…