第一章:hibernate validate入门
1:搭建
1.1:下载架包4.0.2版本的架包。为什么使用该版本,在hibernate validate项目应用中进行说明。
1.2:解压下载的压缩包,导入hibernate-validator和validation-api架包
1.3:这里面既包含了javax下的约束也包含了org.hibernate 下的约束,在之前的版本中,javax下的约束hibernate是不认的。
2:一个简单的例子
public class Car {
@NotNull(message = "manufacturer not null")
private String manufacturer;
@Min(2)
private int seatCount;
………get,set……
}
public class CarTest {
private static Validator validator;
@BeforeClass
public static void setUp() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
@Test
public void manufactureIsNull() {
Car car = new Car(null, 5);
//1:validate()对一个给定的实体对象中定义的所有约束进行校验
Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car);
Assert.assertEquals(1, constraintViolations.size());
}
}
3:常用的约束种类
A:字段级的约束:
当约束被定义在字段上的时候, 这个字段的值是通过字段访问策略来获取并验证的. 也就是说Bean Validation的实现者会直接访问这个实例变量而不会调用属性的访问器(getter) 即使这个方法存在。静态字段或者属性是不会被校验的
@Min(2)
private int seatCount;
B:属性级的约束
必须遵守JavaBeans规范,且定义在getter上,不能定义在setter上
@NotNull
public String getManufacturer() {
return manufacturer;
}
C:类级的约束
@LeaveHourCheck
@LeaveDateBeforeCheck
public class HrLeave extends FlowBusdocument implements java.io.Serializable {
}
D:约束的继承
不仅会验证RentalCar中的约束,同时会验证Car中的约束
public class RentalCar extends Car {
@NotNull
private String rentalStation;
}
E:对象图
在验证当前对象约束的情况下,也会同时验证driver对象的约束
@Valid
private Person driver;
4:约束的校验
Validator是校验的主要接口,有3个方法能够用来校验整个实体对象或者对象的属性,3个方法都返回Set<ConstraintViolation>
对象,
可以通过如下方法获取实例对象
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
校验方法
1:validate
使用validate()
方法对一个给定的实体对象中定义的所有约束条件进行校验
Car car = new Car(null, false, 5);
//1:validate()对一个给定的实体对象中定义的所有约束进行校验
Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car);
2:validateProperty
通过validateProperty()
可以对一个给定实体对象的单个属性进行校验,需要符合JavaBean命名规范
Car car = new Car(null, false, 5);
Set<ConstraintViolation<Car>> constraintViolations = validator.validateProperty(car, "manufacturer");
3:validateValue
通过validateValue() 方法,你能够校验如果把一个特定的值赋给一个类的某一个属性的话,是否会违反此类中定义的约束条件.
Car car = new Car(null, false, 5);
Set<ConstraintViolation<Car>> constraintViolations = validator.validateValue(Car.class, "manufacturer", null);
约束提示信息
可以直接通过message=”提示信息”;也可以通过message提供模板,具体的错误信息在ValidationMessages.properties(src目录下)中定义
public class Car {
//验证不通过时,message提供一个模板
@Min(value=2,message="{com.pps.annotation.bean.Car.seatCount}")
private int seatCount;
……………………get,set…………………………
}
ValidationMessages.properties中模板的配置
#value是Min注解中value的值 如果是@Length(min=1,max=3),则写成{min},{max}
com.pps.annotation.bean.Car.seatCount=座位数不能少于{value}
@Test
public void manufactureIsNull() {
Car car = new Car(“TEST”, true, 1);
for (ConstraintViolation<Car> constraintViolation : constraintViolations) {
System.out.println(constraintViolation.getMessage());
}
Assert.assertEquals(1, constraintViolations.size());
}
输出:座位数不能少于2
5:校验组
在校验的时候,可以选择应用那些约束条件。
eg:一个员工类可能有20个字段,针对不同的操作可能需要验证的约束也不同。添加的时候可能需要验证姓名,密码,地址,电话,性别…..;登录的时候只需要验证姓名,密码。这时候可以通过添加组,来进行验证
一个校验组序列中包含的校验组和这个校验组序列不能造成直接或者间接的循环引用. 包括校验组继承. 如果造成了循环引用的话, 会导致GroupDefinitionException异常.
1:添加约束时,指定所属的组
@NotNull(message = "{com.pps.annotation.bean.Car.manufacturer}")
private String manufacturer;
@AssertTrue(groups=CarChecks.class)
private boolean passedVehicleInspection;
@AssertTrue(groups=CarChecks.class)
private boolean isRegistered;
@Min(value=2,message="{com.pps.annotation.bean.Car.seatCount}",groups=SeatGroup.class)
private int seatCount;
2:组只是一个标识,是一个接口,同时可以继承其他的组
public interface CarChecks {}
3:验证组下面的约束
Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car); //验证default组下的约束
Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car, CarChecks.class);
Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car, SeatGroup.class, Default.class);
5:内置约束
Bean Validator
@Null
@NotNull
@Size
@Min
@Max
@AssertTrue
@AssertFalse
@DecimalMax
@DecimalMin
@Digits
@Future
@Past
@Pattern
@Valid
Hibernate Validator
@CreditCardNumber
@Length
@NotBlank
@NotEmpty
@Range
@SafeHtml
@ScriptAssert
@URL
6:自定义约束(hibernate validate中,4.0和3.6创建方式不同)
创建自己的约束规则一般需要3步:创建约束的标注,实现一个验证器,定义默认的验证错误信息
A:创建约束标注
//该注解可以应用在:方法,域,注解类型上
@Target({ElementType.METHOD,ElementType.FIELD,ElementType.ANNOTATION_TYPE})
//注解在运行期通过反射读取
@Retention(RetentionPolicy.RUNTIME)
//注解使用的约束类
@Constraint(validatedBy=CheckCaseValidator.class)
//在生成JavaDoc时,该注解会被添加到java文档中
@Documented
public @interface CheckCase {
//定义错误消息,可以直接使用错误提示内容,也可以使用模板
String message() default "{com.pps.myannotation.CheckCase.message}";
//定义所在的组
Class<?>[] groups() default {};
//定义级别条件的严重级别
Class<? extends Payload>[] payload() default {};
int value();
}
B:实现验证器
public class IntMinValidator implements ConstraintValidator<CheckCase, Integer> {
private IntMin min;
@Override
public void initialize(CheckCase arg0) {
this.min = arg0;
}
/**
* arg0:用户输入的内容
*/
@Override
public boolean isValid(Integer arg0, ConstraintValidatorContext arg1) {
boolean flag = true;
if (arg0.compareTo(min.value()) < 0) {
flag = false;
}
//可以重新定义模板
/*if (!flag) {
arg1.disableDefaultConstraintViolation();
arg1.buildConstraintViolationWithTemplate(
"{com.pps.myannotation.CheckCaseValidator.message}")
.addConstraintViolation();
}*/
return flag;
}
}
C:自定义约束的使用
@CheckCase(value=5)
private int seat;