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 组的校验就通过了.