Java Bean验证基础

1. 概述

在这篇快速文章中,我们将介绍使用标准框架-JSR 380(也称为Bean验证2.0)来验证Java Bean的基础。
在大多数应用程序中,验证用户输入是一个非常普遍的要求,并且Java Bean验证框架已成为处理这种逻辑的实际标准。

2. JSR380

JSR380是用于Java Bean验证的Java API规范,是Jakarta EE和JavaSE的一部分,它使用@ NotNull,@Min和@Max等注解来确保Bean的属性满足特定条件。
该版本需要Java8或更高版本,并利用Java8中添加的新功能(例如类型注解),并支持新类型(例如Optional和LocalDate)。
有关规范的完整信息,请继续阅读JSR380

3. 依赖关系

我们将使用Maven管理依赖关系。

3.1. Validation API

根据JSR380规范,validation-api依赖项包含标准的验证API:

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

3.2. Validation API的参考实现

Hibernate Validator是Validation API的参考实现。
要使用它,我们必须添加以下依赖项:

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

这里有一点需要说明,hibernate-validatorHibernate的数据持久化方面是完全分开,添加hibernate-validator的依赖项,我们并没有将持久化方面的依赖添加到项目中。

3.3. 表达语言依赖项

JSR380支持变量插值,从而允许在违规消息中使用表达式。
要解析这些表达式,我们必须添加对表达式语言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>3.0.0</version>
</dependency>

如果未添加这些JAR,则在运行时您将收到一条错误消息,如下所示:

HV000183: Unable to load ‘javax.el.ExpressionFactory’. Check that you have the EL dependencies on the classpath, or use ParameterMessageInterpolator instead

4. 使用Validation注解

这里我们将使用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 = "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;
 
    //setters/getters 
}

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

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

一些注解接受其他属性,但是message属性对所有注解都是通用的。这是通常在相应属性的值未通过验证时呈现的消息。
还有一些其他的注解:

  • @NotEmpty:验证该属性不为null或为空;可以应用于String, Collection, Map或者是数组。
  • @NotBlank:只能应用于文本值,并验证该属性不是null或是空格。
  • @Positive@PositiveOrZero:适用于数值并验证其严格为正,或为正(包括0)。
  • @Negative@NegativeOrZero:适用于数值并验证其严格为负数,或包含0的负数。
  • @Past@PastOrPresent:验证日期值是过去时或是包括现在的过去时;可以应用于日期类型,包括Java8中添加的日期类型。
  • @Future@FutureOrPresent:验证日期值是将来的日期或是包括现在将来的日期。
    验证注解也可以应用于集合的元素:
List<@NotBlank String> preferences;

在这种情况下,将验证添加到preferences列表的任何值。
该规范还支持Java8中的新Optional类型:

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

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

5. 验证Bean

诸如Spring之类的某些框架具有仅通过使用注解来触发验证过程的简单方法。这主要是因为我们不必与编程验证API进行交互。
现在让我们走手动路线,以编程方式进行设置:

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

要验证bean,首先必须有一个Validator对象,该对象是使用ValidatorFactory构造的。
下面看一下完成的验证代码:

public class ValidationIntegrationTest {
    private Validator validator;

    @Before
    public void setup() {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        validator = factory.getValidator();
    }

    private User createUser() {
        User user = new User();
        user.setName("John");
        user.setWorking(true);
        //user.setAge(18);
        user.setEmail("lxm");
        //user.setAboutMe(".......................!");
        return user;
    }

    @Test
    public void test1() {
        User user = createUser();
        Set<ConstraintViolation<User>> violations = validator.validate(user);
        if (!violations.isEmpty()){
            violations.forEach((tem)->{
                System.out.println(tem.getPropertyPath().toString() + ":" + tem.getMessage());
            });
        }
    }
}
/*
age:Age should not be less than 18
email:Email should be valid
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值