# Hibernate 验证器 – Java Bean 验证示例

> 原文： [https://howtodoinjava.com/hibernate/hibernate-validator-java-bean-validation/](https://howtodoinjava.com/hibernate/hibernate-validator-java-bean-validation/)

使用 **Hiberate 验证器**验证 Java bean 字段的 Java 示例。 **Bean 验证 API 2** （`JSR-380`）提供了一些流行的注解，可以将这些注解附加到每个 Bean 属性，以保持数据完整性。

## 1\. Maven 依赖

以下是必需的 **Hiberate 验证器 maven 依赖项**。

Bean 验证允许错误消息中包含表达式。 要解析这些表达式，我们必须添加对表达式语言 API 以及该 API 实现的依赖。 我使用 Jboss 的`javax.el`中实现的`javax.el-api`规范添加了它们。

```java
<!-- Java bean validation API - Spec -->
<dependency>
	<groupId>javax.validation</groupId>
	<artifactId>validation-api</artifactId>
	<version>2.0.1.Final</version>
</dependency>

<!-- Hibernate validator - Bean validation API Implementation -->
<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-validator</artifactId>
	<version>6.0.11.Final</version>
</dependency>

<!-- Verify validation annotations usage at compile time -->
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-validator-annotation-processor</artifactId>
  <version>6.0.11.Final</version>
</dependency>

<!-- Unified Expression Language - Spec -->
<dependency>
	<groupId>javax.el</groupId>
	<artifactId>javax.el-api</artifactId>
	<version>3.0.1-b06</version>
</dependency>

<!-- Unified Expression Language - Implementation -->
<dependency>
	<groupId>org.glassfish.web</groupId>
	<artifactId>javax.el</artifactId>
	<version>2.2.6</version>
</dependency>

```

## 2\. Hibernate 验证器示例

#### 2.1 带有验证注解的模型

```java
package com.howtodoinjava.example.model;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class User {

    @NotNull(message = "Please enter id")
    private Long id;

    @Size(max = 20, min = 3, message = "{user.name.invalid}")
    @NotEmpty(message = "Please enter name")
    private String name;

    @Email(message = "{user.email.invalid}")
    @NotEmpty(message = "Please enter email")
    private String email;

    public User(Long id, String name, String email) {
        super();
        this.id = id;
        this.name = name;
        this.email = email;
    }

    //Setters and Getters
}

```

#### 2.2 消息属性

默认情况下，所有消息都是从类路径中的`ValidationMessages.properties`文件解析的。 如果文件不存在，则不会发生[消息解析](https://howtodoinjava.com/spring-core/resolving-text-messages-in-spring-resourcebundlemessagesource-example/)。

```java
user.name.invalid=Invalid Username
user.email.invalid=Invalid Email

```

#### 2.3 执行验证

现在，让我们在`User`实例上执行 bean 验证。

```java
package com.howtodoinjava.example;

import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import com.howtodoinjava.example.model.User;

public class TestHibernateValidator 
{
    public static void main(String[] args) 
    {
        //Create ValidatorFactory which returns validator
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();

        //It validates bean instances
        Validator validator = factory.getValidator();

        User user = new User(null, "1", "abcgmail.com");

        //Validate bean
        Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);

        //Show errors
        if (constraintViolations.size() > 0) {
            for (ConstraintViolation<User> violation : constraintViolations) {
                System.out.println(violation.getMessage());
            }
        } else {
            System.out.println("Valid Object");
        }
    }
}

```

程序输出：

```java
Please enter id
Invalid Email
Invalid Username

```

## 3\. 自定义资源包

默认情况下，框架从[类路径](https://howtodoinjava.com/java/basics/java-set-classpath-command-line-examples/)中的`ValidationMessages.properties`文件中提取验证消息。 您可以如下配置自己的**自定义属性文件**。

将这两个文件放在类路径中，即`messages.properties`和`otherMessages.properties`。 现在，将从这两个属性文件解析所有消息。

```java
Validator validator = Validation.byDefaultProvider()
        .configure()
        .messageInterpolator(
                new ResourceBundleMessageInterpolator(
                        new AggregateResourceBundleLocator(
                                Arrays.asList(
                                        "messages",
                                        "otherMessages"
                                )
                        )
                )
        )
        .buildValidatorFactory()
        .getValidator();

```

## 4\. 消息插值

#### 4.1 邮件参数解析

在消息解析期间，可以使用运行时值使验证消息更有意义。 消息中的**参数值解析以两种方式发生：**

1.  要解析注解属性中的值，只需将大括号括起来即可。 例如。 `{min}`或`{max}`。
2.  要解析字段的运行时值，请使用占位符`${validatedValue}`。

#### 4.2）参数解析示例

*   带有消息和参数的属性文件。

    ```java
    user.name.invalid='${validatedValue}' is an invalid name. It must be minimum {min} chars and maximum {max} chars.

    ```

*   带有验证注解的 Bean 字段。

    ```java
    @Size(max = 20, min = 3, message = "{user.name.invalid}")
    private String name;

    ```

*   程序输出中已解决的消息。

    ```java
    User user = new User(23l, "xy", "abc@gmail.com");
    Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);

    //Output

    'xy' is an invalid name. It must be minimum 3 chars and maximum 20 chars.

    ```

## 5\. Hiberate 验证器注解

现在，当我们知道如何以编程方式使用 Hiberate 验证器时。 让我们看一下可以在 bean 类中使用的所有注解。

#### 5.1 Bean 验证注解

| 注解 | 描述 |
| --- | --- |
| `@Digits(integer=, fraction=)` | 检查注解的值是否为最多`integer`位和`fractional`小数位的数字。 |
| `@Email` | 检查指定的字符序列是否为有效的电子邮件地址。 |
| `@Max(value=)` | 检查带注解的值是否小于或等于指定的最大值。 |
| `@Min(value=)` | 检查带注解的值是否大于或等于指定的最小值 |
| `@NotBlank` | 检查带注解的字符序列不为空，并且修剪后的长度大于 0。 |
| `@NotEmpty` | 检查带注解的元素是否不为`null`或为空。 |
| `@Null` | 检查带注解的值是否为空 |
| `@NotNull` | 检查带注解的值不为空 |
| `@Pattern(regex=, flags=)` | 考虑给定的`flag`匹配项，检查带注解的字符串是否与正则表达式`regex`匹配 |
| `@Size(min=, max=)` | 检查带注解的元素的大小是否在最小和最大（包括）之间 |
| `@Negative` | 检查元素是否严格为负。 零值被视为无效。 |
| `@NegativeOrZero` | 检查元素是负数还是零。 |
| `@Future` | 检查带注解的日期是否是将来的日期。 |
| `@FutureOrPresent` | 检查带注解的日期是现在还是将来。 |
| `@PastOrPresent` | 检查带注解的日期是过去还是现在。 |

#### 5.2 Hiberate 验证器特定的注解

除了 Bean 验证 API 定义的约束之外，Hibernate 验证器还提供了以下有用的自定义约束。

| 注解 | 描述 |
| --- | --- |
| `@CreditCardNumber( ignoreNonDigitCharacters=)` | 检查带注解的字符序列是否通过了 [Luhn 校验和](https://en.wikipedia.org/wiki/Luhn_algorithm)测试。 请注意，此验证旨在检查用户错误，而不是信用卡有效性！ |
| `@Currency(value=)` | 检查带注解的`javax.money.MonetaryAmount`的货币单位是否为指定货币单位的一部分。 |
| `@EAN` | 检查带注解的字符序列是否为有效的 [EAN](https://en.wikipedia.org/wiki/International_Article_Number_%28EAN%29) 条形码。 默认值为 EAN-13。 |
| `@ISBN` | 检查带注解的字符序列是否为有效的 [ISBN](https://en.wikipedia.org/wiki/International_Standard_Book_Number) 。 |
| `@Length(min=, max=)` | 验证带注解的字符序列是否在`min`和`max`之间。 |
| `@Range(min=, max=)` | 检查带注解的值是否介于（包括）指定的最小值和最大值之间。 |
| `@UniqueElements` | 检查带注解的集合仅包含唯一元素。 |
| `@URL` | 根据 RFC2396 检查带注解的字符序列是否为有效 URL。 |

将我的问题放在评论部分。

学习愉快！

参考文献：

[Bean 验证 2.0](https://beanvalidation.org/)

[Hiberate 验证器注解处理器](http://hibernate.org/validator/tooling/)