Hibernate Validator 6.0.7.Final 起步

介绍JSR380-BeanValidation2.0的基本用法,演示如何通过Hibernate Validator实现Java对象的属性校验,提高代码质量和维护效率。

数据校验是一个很常见的工作,它贯穿于各个层次,从展现层到持久层。通常情况下,如果同样的校验逻辑被应用到各个层次的话,非常容易出错,也很耗时。为了避免重复的校验,开发者通常将校验逻辑绑定到模型上;这样做,校验逻辑看起来就像是模型类的元数据一样。
对比下面2张图看一下:
这里写图片描述
这里写图片描述
第一张图中,校验逻辑散布在各个层次;第二张图中,校验逻辑集中到模型中。

JSR 380 - Bean Validation 2.0 为数据模型和方法的校验定义了元数据模型和API。
下面,以一个入门案例感性地认识一下。

  • 引入依赖,我们只需要引入hibernate-validator就行了,它会间接引入validation-api
<dependency>
	<groupId>org.hibernate.validator</groupId>
	<artifactId>hibernate-validator</artifactId>
	<version>6.0.7.Final</version>
</dependency>
  • 注意,如果是在非web环境下,我们还需要引入以下依赖
<dependency>
	<!-- 从名字就可以看出来,这个依赖是关于EL表达式的。
		具体到这里,这个依赖就是为了做消息提示中的表达式计算的。
		比如,国际化消息提示中的 org.hibernate.validator.constraints.Length.message=length must be between {min} and {max}-->
	<groupId>org.glassfish</groupId>
	<artifactId>javax.el</artifactId>
	<version>3.0.1-b08</version>
</dependency>

<dependency>
	<groupId>org.hibernate.validator</groupId>
	<artifactId>hibernate-validator-cdi</artifactId>
	<version>6.0.7.Final</version>
</dependency>
  • 接下来定义一个model,并对其属性应用约束
public class Car {

    @NotNull(message = "must not be null")
    private String manufacturer;

    @NotNull
    @Size(min = 2, max = 14, message = "size must be between 2 and 14")
    private String licensePlate;

    @Min(value = 2, message = "must bigger than 2")
    private int seatCount;

    public Car(String manufacturer, String licensePlate, int seatCount) {
        this.manufacturer = manufacturer;
        this.licensePlate = licensePlate;
        this.seatCount = seatCount;
    }

    public String getManufacturer() {
        return manufacturer;
    }

    public void setManufacturer(String manufacturer) {
        this.manufacturer = manufacturer;
    }

    public String getLicensePlate() {
        return licensePlate;
    }

    public void setLicensePlate(String licensePlate) {
        this.licensePlate = licensePlate;
    }

    public int getSeatCount() {
        return seatCount;
    }

    public void setSeatCount(int seatCount) {
        this.seatCount = seatCount;
    }
}
  • 使用Validator的实例验证这些约束
public class CarTest {

    private static Validator validator;

    @BeforeClass
    public static void setUpValidator() {
	    // 通过工厂获取到一个Validator的实例
        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
        validator = validatorFactory.getValidator();
    }

    @Test
    public void manufacturerIsNull() {
        // 只有一个违反了约束,manufacturer 属性不能为空
        Car car = new Car(null, "DD-AB-123", 4);

        Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car);
		// 我们知道,上面创建的Car违反了一个约束
        Assert.assertEquals(1, constraintViolations.size());
        // 并且这个约束对应的消息我们也知道
        Assert.assertEquals("must not be null",
                constraintViolations.iterator().next().getMessage());
    }

    @Test
    public void licensePlateTooShort() {
        // 只违反了一个约束,licensePlate 属性的长度必须在2和14之间
        Car car = new Car("Morris", "D", 4);

        Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car);

        Assert.assertEquals(1, constraintViolations.size());
        Assert.assertEquals("size must be between 2 and 14",
                constraintViolations.iterator().next().getMessage());
    }

    @Test
    public void seatCountTooLow() {
        // 只违反了一个约束,seatCount 属性的值不能小于2
        Car car = new Car("Morris", "DD-AB-123", 1);

        Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car);

        Assert.assertEquals(1, constraintViolations.size());
        Assert.assertEquals("must bigger than 2",
                constraintViolations.iterator().next().getMessage());
    }

    @Test
    public void carIsValid() {
        // 没有违反约束
        Car car = new Car("Morris", "DD-AB-123", 4);

        Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car);

        Assert.assertEquals(0, constraintViolations.size());
    }
}

本文只是个入门,对数据校验有一个感性的认识,实际项目中,我们并不会像本例这样使用Validator接口的来手动校验。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杂货铺的小掌柜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值