本文翻译自Baeldung。
在这个快速教程中,我们将介绍使用标准的JSR-380框架及其基于Java EE 7引入的Jakarta Bean Validation 3.0规范对Java bean进行验证的基础知识。
在大多数应用程序中,验证用户输入是一项非常常见的需求,而Java Bean Validation框架已经成为处理此类逻辑的事实标准。
JSR 380是Java API的一个规范,用于对bean进行验证,属于Jakarta EE和JavaSE的一部分。它确保bean的属性满足特定的标准,使用诸如@NotNull
、@Min
和@Max
等注解。
此版本需要Java 17或更高版本,因为它使用了Spring Boot 3.x,该版本带来了Hibernate-Validator 8.0.0。它还支持Java 9及以上版本引入的新功能,如流和Optional
改进、模块、私有接口方法等。
要获取有关规范的完整信息,我们可以阅读JSR 380的内容。
在最新版本的spring-boot-starter-validation中,除了其他依赖项之外,还将提供hibernate-validator的传递依赖项。
如果我们只想添加验证的依赖项,可以简单地在我们的pom.xml中添加hibernate-validator:
<dependency>
<groupId>org.hibernate.validatorgroupId>
<artifactId>hibernate-validatorartifactId>
<version>8.0.0.Finalversion>
dependency>
注意:hibernate-validator与Hibernate的持久化方面完全分离。因此,通过将其添加为依赖项,我们不会将这些持久化方面添加到项目中。
这里,我们将使用一个名为User
的Java bean,并添加一些简单的验证逻辑:
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import jakarta.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
验证属性不为空。我们可以将其应用于字符串、集合、映射或数组值。@NotBlank
只能应用于文本值,并验证属性不为 null
或空白。@Positive
和 @PositiveOrZero
适用于数值,验证它们严格为正,或者包括 0。@Negative
和 @NegativeOrZero
适用于数值,验证它们严格为负,或者包括 0。@Past
和 @PastOrPresent
验证日期值在过去,或者过去包括现在。我们可以将其应用于日期类型,包括 Java 8 中添加的日期类型。@Future
和 @FutureOrPresent
验证日期值在将来,或者在将来包括现在。我们还可以对集合中的元素应用校验注解:
List<@NotBlank String> preferences;
在这种情况下,添加到 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
构建的。
然后我们将用一个空的名称值来设置这个无效的用户:
User user = new User();
user.setWorking(true);
user.setAboutMe("Its all about me!");
user.setAge(50);
现在我们有了一个Validator
,我们可以通过将其传递给validate
方法来验证我们的Bean。
在User
对象中定义的约束的任何违规都将作为一个Set
返回:
Set<ConstraintViolation<User>> violations = validator.validate(user);
通过迭代违规,我们可以使用getMessage
方法获取所有的违规消息:
for (ConstraintViolation<User> violation : violations) {
log.error(violation.getMessage());
}
在我们的示例中(如果ifNameIsNull_nameValidationFails
),集合将包含一条约束违规,消息为“名称不能为空”。
在本文中,我们专注于通过标准的Java验证API进行简单的验证。我们展示了使用 jakarta.validation
注解和API的Bean验证的基础知识。
如往常一样,本文中概念的实现以及所有代码片段都可以在 GitHub 上找到。