hibernate_validator_06

认证组(校验组)

校验组能够让你在验证的时候选择应用哪些约束条件. 这样在某些情况下( 例如向导 ) 就可以
对每一步进行校验的时候, 选取对应这步的那些约束条件进行验证了. 校验组是通过可变参数传
递给 validate , validateProperty 和 validateValue 的.

注意:

如果某个约束条件属于多个组,那么各个组在校验时候的顺序是不可预知的. 如果
一个约束条件没有被指明属于哪个组,那么它就会被归类到默认组
( javax.validation.groups.Default ).

第一步我们创建两个接口作为认证组:

package test01;

/**
 * @author Administrator
 *汽车驾驶员检查组
 */
public interface DriverChecks {

}


package test01;

/**
 * @author Administrator
 *汽车车辆检查
 */
public interface CarChecks {

}

第二步我们定义Person类,具有name的属性

package test01;

import javax.validation.constraints.NotNull;

public class Person {
    /**
     * 姓名
     */
    @NotNull
    private String name;
    public Person(String name) {
    this.name = name;
    }
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
    

}

第三步:创建一个驾驶人继承Person类:

package test01;

import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Min;

public class Driver extends Person {
    /**
     * 年龄
     */
    @Min(value = 18, message = "You have to be 18 to drive a car", groups = DriverChecks.class)
    public int age;
    
    /**
     * 是否有驾照
     */
    @AssertTrue(message = "You first have to pass the driving test", groups = DriverChecks.class)
    public boolean hasDrivingLicense;
    
    public Driver(String name) {
    super( name );
    }
    
    public void passedDrivingTest(boolean b) {
        hasDrivingLicense = b;
        }

    /**
     * @return the age
     */
    public int getAge() {
        return age;
    }

    /**
     * @param age the age to set
     */
    public void setAge(int age) {
        this.age = age;
    }

    /**
     * @return the hasDrivingLicense
     */
    public boolean isHasDrivingLicense() {
        return hasDrivingLicense;
    }

    /**
     * @param hasDrivingLicense the hasDrivingLicense to set
     */
    public void setHasDrivingLicense(boolean hasDrivingLicense) {
        this.hasDrivingLicense = hasDrivingLicense;
    }
    
}

第四步:创建一个车Car类

package test01;

import javax.validation.Valid;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

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  inspectionfirst", groups = CarChecks.class)
    private boolean passedVehicleInspection;
    
    /**
     * 驾驶员
     */
    @Valid
    private Driver driver;
    
    public Car(String manufacturer, String licencePlate, int seatCount) {
    this.manufacturer = manufacturer;
    this.licensePlate = licencePlate;
    this.seatCount = seatCount;
    }
    /**
     * @return the manufacturer
     */
    public String getManufacturer() {
        return manufacturer;
    }
    /**
     * @param manufacturer the manufacturer to set
     */
    public void setManufacturer(String manufacturer) {
        this.manufacturer = manufacturer;
    }
    /**
     * @return the licensePlate
     */
    public String getLicensePlate() {
        return licensePlate;
    }
    /**
     * @param licensePlate the licensePlate to set
     */
    public void setLicensePlate(String licensePlate) {
        this.licensePlate = licensePlate;
    }
    /**
     * @return the seatCount
     */
    public int getSeatCount() {
        return seatCount;
    }
    /**
     * @param seatCount the seatCount to set
     */
    public void setSeatCount(int seatCount) {
        this.seatCount = seatCount;
    }
    /**
     * @return the passedVehicleInspection
     */
    public boolean isPassedVehicleInspection() {
        return passedVehicleInspection;
    }
    /**
     * @param passedVehicleInspection the passedVehicleInspection to set
     */
    public void setPassedVehicleInspection(boolean passedVehicleInspection) {
        this.passedVehicleInspection = passedVehicleInspection;
    }
    /**
     * @return the driver
     */
    public Driver getDriver() {
        return driver;
    }
    /**
     * @param driver the driver to set
     */
    public void setDriver(Driver driver) {
        this.driver = driver;
    }
    
}

现在, 在我们的例子中有三个不同的校验组, Person.name, Car.manufacturer,
Car.licensePlate 和 Car.seatCount都属于默认( Default ) 组, Driver.age 和
Driver.hasDrivingLicense 从属于 DriverChecks 组, 而Car.passedVehicleInspection
在 CarChecks 组中. 下面演示了如何让 Validator.validate 验证不同的组来得到
不同的校验结果.

最后,进行验证:

package test01;

import static org.junit.Assert.*;

import java.util.Set;

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

import org.junit.BeforeClass;
import org.junit.Test;

public class GroupTest {
    private static Validator validator;

    /**
     * 获取一个验证器
     */
    @BeforeClass
    public static void setUp() {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        validator = factory.getValidator();
    }

    @Test
    public void driveAway() {
        // create a car and check that everything is ok with it.
        Car car = new Car("Morris", "DD-AB-123", 2);
        Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car);
        assertEquals(0, constraintViolations.size());
        // but has it passed the vehicle inspection?
        constraintViolations = validator.validate(car, CarChecks.class);
        assertEquals(1, constraintViolations.size());
        assertEquals("The  car  has  to  pass  the  vehicle  inspectionfirst",constraintViolations.iterator().next().getMessage());
        // let's go to the vehicle inspection
        car.setPassedVehicleInspection(true);
        assertEquals(0, validator.validate(car).size());
        // now let's add a driver. He is 18, but has not passed the driving test
        // yet
        Driver john = new Driver("John Doe");
        john.setAge(18);
        car.setDriver(john);
        constraintViolations = validator.validate(car, DriverChecks.class);
        assertEquals(1, constraintViolations.size());
        assertEquals("You  first  have  to  pass  the  drivingtest",constraintViolations.iterator().next().getMessage());
        // ok, John passes the test
        john.passedDrivingTest(true);
        assertEquals(0, validator.validate(car, DriverChecks.class).size());
        // just checking that everything is in order now
        assertEquals(0, validator.validate(car, Default.class, CarChecks.class, DriverChecks.class).size());
    }
}

 其实我们发现:

即使
passedVehicleInspection的默认值是 false 也不会校验出错误来. 因为定义在这个属性上的约束
条件并不属于默认的校验组, 接下来,我们来校验 CarChecks 这个组, 这样就会发现car违反了约束
条件, 必须让这个车先通过检测. 接下来,我们给这个车增加一个司机, 然后在基于 DriverChecks 来
校验, 会发现因为这个司机因为还没有通过驾照考试, 所以又一次得到了校验错误, 如果我们设
置passedDrivingTest属性为 true 之后, DriverChecks 组的校验就通过了.

原文地址:https://www.cnblogs.com/wangyang108/p/5669511.html