Hibernate Validator 6.0.7 Final 之五(初识分组校验)

首先,解释一下什么是分组校验?所谓分组,就是允许我们在校验过程中指定使用哪些约束。比如说:一个被校验的bean有10个属性。在某次校验中,我们只想校验前5个属性,后5个属性不想校验(也就是说,定义在前5个属性上的约束生效,而定义在后5个属性上的约束不生效);在另一次校验中,我们只想校验后5个属性,而不想校验前5个属性。要实现这个目标,我们可以对属性进行分组,然后在实际校验的时候明确指定我们要校验哪个或者哪些分组。下面通过实例来解释这个话题:

  1. Person类
public class Person {

    /**
     * 没有明确指定分组的话,默认使用的是
     *
     * {@link javax.validation.groups.Default}
     *
     * 分组,而不是空
     *  
     * 也就是说,当分组为 Default 的时候,name属性不能为空
     */
    @NotNull
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}
  1. Driver
public class Driver extends Person {

    @Min(value = 18, message = "You have to be 18 to drive a car", groups = DriverChecks.class)
    private int age;

    @AssertTrue(message = "You first have to pass the driving test", groups = DriverChecks.class)
    private boolean hasDrivingLicense;

    public Driver(String name) {
        super(name);
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isHasDrivingLicense() {
        return hasDrivingLicense;
    }

    public void setHasDrivingLicense(boolean hasDrivingLicense) {
        this.hasDrivingLicense = hasDrivingLicense;
    }

}

需要注意的是,在Driver的定义中,我们为age和hasDrivingLicense属性的校验明确指定了分组--DriverCheck,其定义如下:

public interface DriverChecks {

}

可以看出,所谓分组,其实只是一个简单的标记接口。

  1. Car
public class Car {

    @NotNull
    private String manufacturer;

    @NotNull
    @Size(min = 2, max = 14)
    private String licensePlate;

    @Min(2)
    private int seatCount;

    @AssertTrue(message = "The car has to pass the vehicle inspection first",
            groups = CarChecks.class)
    private boolean passedVehicleInspection;

    @Valid
    private Driver driver;

    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;
    }

    public boolean isPassedVehicleInspection() {
        return passedVehicleInspection;
    }

    public void setPassedVehicleInspection(boolean passedVehicleInspection) {
        this.passedVehicleInspection = passedVehicleInspection;
    }

    public Driver getDriver() {
        return driver;
    }

    public void setDriver(Driver driver) {
        this.driver = driver;
    }

}

和Driver类似,我们为Car的passedVehicleInspection属性指定了分组--CarChecks,其定义如下:

public interface CarChecks {

}

至此,我们需要总结一下:

  • 定义在Person的name属性、Car的manufacturer属性、Car的licensePlate属性和Car的seatCount属性上面的约束都属于 Default 分组(因为没有明确指定分组)
  • 定义在Driver的age和hasDrivingLicense属性上面的约束都属于 DriverChecks 分组
  • 定义在Car的passedVehicleInspection属性上面的约束属于CarChecks分组

最后,我们通过测试看一下分组校验的效果:

    @Test
    public void groupValidateFirstTest() {
        Car car = new Car("Morris", "DD-AB-123", 2);
        // 校验 car 对象的属于 Default 分组的属性
        Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car);
        assertEquals(0, constraintViolations.size());

        // 校验 car 对象的属于 CarChecks 分组的属性
        constraintViolations = validator.validate(car, CarChecks.class);
        assertEquals(1, constraintViolations.size());
        assertEquals("The car has to pass the vehicle inspection first",
                constraintViolations.iterator().next().getMessage());

        // 校验 car 对象的属于 CarChecks 分组的属性
        car.setPassedVehicleInspection(true);
        assertEquals(0, validator.validate(car, CarChecks.class).size());
        
        // 默认情况下,jhon没有通过驾驶测试,因为布尔值的默认值是false
        Driver john = new Driver("John Doe");
        john.setAge(18);
        car.setDriver(john);
        // 校验 driver 对象的属于 DriverChecks 分组的属性
        constraintViolations = validator.validate(car, DriverChecks.class);
        assertEquals(1, constraintViolations.size());
        assertEquals("You first have to pass the driving test",
                constraintViolations.iterator().next().getMessage());

        // 让john通过驾驶测试
        john.setHasDrivingLicense(true);
        assertEquals(0, validator.validate(car, DriverChecks.class).size());

        // 校验所有分组
        assertEquals(0,
                validator.validate(car, Default.class, CarChecks.class, DriverChecks.class).size());
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值