【hibernate validator】(二)声明和验证Bean约束(上)

简介: 【hibernate validator】(二)声明和验证Bean约束

首发博客地址

https://blog.zysicyj.top/

一、声明bean约束

1. 字段级别约束

  1. 不支持静态类型字段
  2. 验证引擎直接访问实例变量,不会调用属性的访问器
  3. 在验证字节码增强的对象时,应适用属性级别约束,因为字节码增库无法通过反射确定字段访问
package org.hibernate.validator.referenceguide.chapter02.fieldlevel;
public class Car {
    @NotNull
    private String manufacturer;
    @AssertTrue
    private boolean isRegistered;
    public Car(String manufacturer, boolean isRegistered) {
        this.manufacturer = manufacturer;
        this.isRegistered = isRegistered;
    }
    //getters and setters...
}

2. 属性级别约束

  1. 必须注释getter而不是setter,这样可以限制没有设置方法的只读属性
  2. 该级别将使用属性访问策略来访问验证的值,即验证引擎通过属性访问器来访问数据
  3. 不要字段和getter都加校验,这样会导致校验两次
package org.hibernate.validator.referenceguide.chapter02.propertylevel;
public class Car {
    private String manufacturer;
    private boolean isRegistered;
    public Car(String manufacturer, boolean isRegistered) {
        this.manufacturer = manufacturer;
        this.isRegistered = isRegistered;
    }
    @NotNull
    public String getManufacturer() {
        return manufacturer;
    }
    public void setManufacturer(String manufacturer) {
        this.manufacturer = manufacturer;
    }
    @AssertTrue
    public boolean isRegistered() {
        return isRegistered;
    }
    public void setRegistered(boolean isRegistered) {
        this.isRegistered = isRegistered;
    }
}
  1. 容器元素约束

3.1 Iterable

在该类型上加约束时,将会校验每个元素

package org.hibernate.validator.referenceguide.chapter02.containerelement.set;
import java.util.HashSet;
import java.util.Set;
public class Car {
    private Set<@ValidPart String> parts = new HashSet<>();
    public void addPart(String part) {
        parts.add( part );
    }
    //...
}
Car car = new Car();
car.addPart( "Wheel" );
car.addPart( null );
Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car );
assertEquals( 1, constraintViolations.size() );
ConstraintViolation<Car> constraintViolation =
        constraintViolations.iterator().next();
assertEquals(
        "'null' is not a valid car part.",
        constraintViolation.getMessage()
);
assertEquals( "parts[].<iterable element>",
        constraintViolation.getPropertyPath().toString() );

3.2 List

也会校验每个元素

package org.hibernate.validator.referenceguide.chapter02.containerelement.list;
public class Car {
    private List<@ValidPart String> parts = new ArrayList<>();
    public void addPart(String part) {
        parts.add( part );
    }
    //...
}
Car car = new Car();
car.addPart( "Wheel" );
car.addPart( null );
Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car );
assertEquals( 1, constraintViolations.size() );
ConstraintViolation<Car> constraintViolation =
        constraintViolations.iterator().next();
assertEquals(
        "'null' is not a valid car part.",
        constraintViolation.getMessage()
);
assertEquals( "parts[1].<list element>",
        constraintViolation.getPropertyPath().toString() );

3.3 Map

package org.hibernate.validator.referenceguide.chapter02.containerelement.map;
import java.util.HashMap;
import java.util.Map;
import javax.validation.constraints.NotNull;
public class Car {
    public enum FuelConsumption {
        CITY,
        HIGHWAY
    }
    private Map<@NotNull FuelConsumption, @MaxAllowedFuelConsumption Integer> fuelConsumption = new HashMap<>();
    public void setFuelConsumption(FuelConsumption consumption, int value) {
        fuelConsumption.put( consumption, value );
    }
    //...
}
Car car = new Car();
car.setFuelConsumption( Car.FuelConsumption.HIGHWAY, 20 );
Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car );
assertEquals( 1, constraintViolations.size() );
ConstraintViolation<Car> constraintViolation =
        constraintViolations.iterator().next();
assertEquals(
        "20 is outside the max fuel consumption.",
        constraintViolation.getMessage()
);
assertEquals(
        "fuelConsumption[HIGHWAY].<map value>",
        constraintViolation.getPropertyPath().toString()
);
Car car = new Car();
car.setFuelConsumption( null, 5 );
Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car );
assertEquals( 1, constraintViolations.size() );
ConstraintViolation<Car> constraintViolation =
        constraintViolations.iterator().next();
assertEquals(
        "must not be null",
        constraintViolation.getMessage()
);
assertEquals(
        "fuelConsumption<K>[].<map key>",
        constraintViolation.getPropertyPath().toString()
);

3.4 Optional

package org.hibernate.validator.referenceguide.chapter02.containerelement.optional;
public class Car {
    private Optional<@MinTowingCapacity(1000) Integer> towingCapacity = Optional.empty();
    public void setTowingCapacity(Integer alias) {
        towingCapacity = Optional.of( alias );
    }
    //...
}
• 1
Car car = new Car();
car.setTowingCapacity( 100 );
Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car );
assertEquals( 1, constraintViolations.size() );
ConstraintViolation<Car> constraintViolation = constraintViolations.iterator().next();
assertEquals(
        "Not enough towing capacity.",
        constraintViolation.getMessage()
);
assertEquals(
        "towingCapacity",
        constraintViolation.getPropertyPath().toString()
);

3.5 自定义容器

package org.hibernate.validator.referenceguide.chapter02.containerelement.custom;
public class Car {
    private GearBox<@MinTorque(100) Gear> gearBox;
    public void setGearBox(GearBox<Gear> gearBox) {
        this.gearBox = gearBox;
    }
    //...
}
package org.hibernate.validator.referenceguide.chapter02.containerelement.custom;
public class GearBox<T extends Gear> {
    private final T gear;
    public GearBox(T gear) {
        this.gear = gear;
    }
    public Gear getGear() {
        return this.gear;
    }
}
package org.hibernate.validator.referenceguide.chapter02.containerelement.custom;
public class Gear {
    private final Integer torque;
    public Gear(Integer torque) {
        this.torque = torque;
    }
    public Integer getTorque() {
        return torque;
    }
    public static class AcmeGear extends Gear {
        public AcmeGear() {
            super( 60 );
        }
    }
}
package org.hibernate.validator.referenceguide.chapter02.containerelement.custom;
public class GearBoxValueExtractor implements ValueExtractor<GearBox<@ExtractedValue ?>> {
    @Override
    public void extractValues(GearBox<@ExtractedValue ?> originalValue, ValueExtractor.ValueReceiver receiver) {
        receiver.value( null, originalValue.getGear() );
    }
}
Car car = new Car();
car.setGearBox( new GearBox<>( new Gear.AcmeGear() ) );
Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car );
assertEquals( 1, constraintViolations.size() );
ConstraintViolation<Car> constraintViolation =
        constraintViolations.iterator().next();
assertEquals(
        "Gear is not providing enough torque.",
        constraintViolation.getMessage()
);
assertEquals(
        "gearBox",
        constraintViolation.getPropertyPath().toString()
);

3.6 嵌套容器元素

package org.hibernate.validator.referenceguide.chapter02.containerelement.nested;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.validation.constraints.NotNull;
public class Car {
    private Map<@NotNull Part, List<@NotNull Manufacturer>> partManufacturers =
            new HashMap<>();
    //...
}

4. 类级别约束

  1. 在这种情况下,验证的对象不是单个属性而是完整的对象
  2. 适合依赖于对象的多个属性之间的相关性很高的场景
package org.hibernate.validator.referenceguide.chapter02.classlevel;
@ValidPassengerCount
public class Car {
    private int seatCount;
    private List<Person> passengers;
    //...
}

5. 约束继承

在一个类实现接口或扩展另一个类时,在超类上声明的所有约束注释都以与该类本身上指定的约束相同的方式约束

package org.hibernate.validator.referenceguide.chapter02.inheritance;
public class Car {
    private String manufacturer;
    @NotNull
    public String getManufacturer() {
        return manufacturer;
    }
    //...
}
package org.hibernate.validator.referenceguide.chapter02.inheritance;
public class RentalCar extends Car {
    private String rentalStation;
    @NotNull
    public String getRentalStation() {
        return rentalStation;
    }
    //...
}
  1. RentalCar 不仅会校验getRentalStation,而且会校验父类的getManufacturer
  2. 若继承换成接口,也是会校验超类的

相关文章
|
8月前
|
Java 数据库连接
【hibernate validator】(五)分组约束
【hibernate validator】(五)分组约束
|
8月前
|
Java 数据库连接
hibernate validator】(三)声明和验证方法约束
hibernate validator】(三)声明和验证方法约束
|
8月前
|
安全 Java 数据库连接
【hibernate validator】(四)内插约束错误消息
【hibernate validator】(四)内插约束错误消息
|
8月前
|
Java 数据库连接 API
【hibernate validator】(二)声明和验证Bean约束(下)
【hibernate validator】(二)声明和验证Bean约束(下)
|
8月前
|
Java 数据库连接
【hibernate validator】(六)创建自定义约束
【hibernate validator】(六)创建自定义约束
|
10月前
|
Oracle 关系型数据库 Java
hibernate操作Oracle出现违反唯一约束条件
出现这个问题的原因无非是主键冲突,我这里引起主键冲突的原因是实体类使用的ID策略为
|
12月前
|
前端开发 Java 数据库连接
Hibernate Validator -- 伟大的校验器
validator Engine 是支持Javax.validator 的接口的实现, 并且可以通过一些简单的标注的形式(annotation形式)实现一个校验的形式, 它其实也是一个约定大于执行的过程
94 0
|
前端开发 Java 数据库连接
源码解析最流行的Validator框架——Hibernate Validator
源码解析最流行的Validator框架——Hibernate Validator
565 0
源码解析最流行的Validator框架——Hibernate Validator
|
Java 数据库连接
[原创]自定义Hibernate Validator校验注解
[原创]自定义Hibernate Validator校验注解
[原创]自定义Hibernate Validator校验注解
|
Java 数据库连接
SpringBoot 2.0参数校验Hibernate Validator
SpringBoot 2.0参数校验Hibernate Validator
SpringBoot 2.0参数校验Hibernate Validator