Hibernate Validator Bean的校验(6.0.17)

Hibernate Validator 6.0.17
1.1 首先需要引入maven pom文件 ,hibernate-validator 需要实现el表达式,需要引入 javax.el(一般javaEE容器都已提供了el实现,可以不需要引入 javax.el maven ,javaSE环境需要引入
<dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.0.17.Final</version>
</dependency>
<dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.el</artifactId>
      <version>3.0.1-b09</version>
</dependency>
解释:Field 和 Properties 区别  Field 是private 修饰不可被访问修改的,如果加个get/set方法就是property。

Field-level constraints

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

字段级别校验可以直接访问被校验的实例字段,does not invoke the property accessor method even if such an accessor exists.可以访问public、private etc等级别,静态字段是不支持的

如果是校验字节码提升对象,就需要用到property level constraints,字节码提升库是不能够通过反射决定字段的

Property-level constraints

如果model对象符合javabean规范,同样可以给bean 的properties注释加以校验
需要用到get方法上而不是set方法上
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;
    }
}

不建议在filed 和 get上都加注释,否则会校验两次

Container element constraints

Hibernate Validator validates container element constraints specified on the following standard Java containers:

  • implementations of java.util.Iterable (e.g. Lists, Sets),

  • implementations of java.util.Map, with support for keys and values,

  • java.util.Optionaljava.util.OptionalIntjava.util.OptionalDoublejava.util.OptionalLong,

  • the various implementations of JavaFX’s javafx.beans.observable.ObservableValue.

6之前容器元素校验需要一个@Valid 注解,6之后就不是必须的
@ValidPart 为自定义校验器
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() );
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 );
    }

    //...

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

Nested container elements

Constraints are also supported on nested container elements.

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<>();

    //...
}

Class-level constraints

不仅是单个属性校验 整个类级别的校验都可以,类级别校验非常有用如果对象不同属性有关联的话。

以下@ValidPassengerCount 加在类级别上,那么校验器就可以访问整个car对象,访问比较座位和乘客的数量。

package org.hibernate.validator.referenceguide.chapter02.classlevel;

@ValidPassengerCount
public class Car {

    private int seatCount;

    private List<Person> passengers;

    //...
}
package org.hibernate.validator.referenceguide.chapter06.classlevel;

@Target({ TYPE, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = { ValidPassengerCountValidator.class })
@Documented
public @interface ValidPassengerCount {

    String message() default "{org.hibernate.validator.referenceguide.chapter06.classlevel." +
            "ValidPassengerCount.message}";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
}
package org.hibernate.validator.referenceguide.chapter06.classlevel;

public class ValidPassengerCountValidator
        implements ConstraintValidator<ValidPassengerCount, Car> {

    @Override
    public void initialize(ValidPassengerCount constraintAnnotation) {
    }

    @Override
    public boolean isValid(Car car, ConstraintValidatorContext context) {
        if ( car == null ) {
            return true;
        }

        return car.getPassengers().size() <= car.getSeatCount();
    }
}

Object graphs

Cascaded validation

package org.hibernate.validator.referenceguide.chapter02.objectgraph;

public class Car {

    @NotNull
    @Valid
    private Person driver;

    //...
}
package org.hibernate.validator.referenceguide.chapter02.objectgraph;

public class Person {

    @NotNull
    private String name;

    //...
}

对象图的校验是递归的,因此不能出现引用自己的情况,保证对象图没有闭环,在cascaded validation中 null值是被忽略的。

对象图也可用在容器中校验,容器参数加上@Valid 那么每个元素都会校验。

package org.hibernate.validator.referenceguide.chapter02.objectgraph.containerelement;

public class Car {

    private List<@NotNull @Valid Person> passengers = new ArrayList<Person>();

    private Map<@Valid Part, List<@Valid Manufacturer>> partManufacturers = new HashMap<>();

    //...
}
package org.hibernate.validator.referenceguide.chapter02.objectgraph.containerelement;

public class Part {

    @NotNull
    private String name;

    //...
}
package org.hibernate.validator.referenceguide.chapter02.objectgraph.containerelement;

public class Manufacturer {

    @NotNull
    private String name;

    //...
}

When validating an instance of the Car class shown in Example 2.12, “Cascaded validation of containers”, a ConstraintViolation will be created:

  • if any of the Person objects contained in the passengers list has a null name;

  • if any of the Part objects contained in the map keys has a null name;

  • if any of the Manufacturer objects contained in the list nested in the map values has a null name.

Validating bean constraints

Obtaining a Validator instance

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();

Validator methods

Validator#validate()

Car car = new Car( null, true );

Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car );

assertEquals( 1, constraintViolations.size() );
assertEquals( "must not be null", constraintViolations.iterator().next().getMessage() );

 

Validator#validateProperty()

Car car = new Car( null, true );

Set<ConstraintViolation<Car>> constraintViolations = validator.validateProperty(
        car,
        "manufacturer"
);

assertEquals( 1, constraintViolations.size() );
assertEquals( "must not be null", constraintViolations.iterator().next().getMessage() );
Validator#validateValue()  // 将某个值 用class filed 上的校验规则进行校验
Set<ConstraintViolation<Car>> constraintViolations = validator.validateValue(
        Car.class,
        "manufacturer",
        null
);

assertEquals( 1, constraintViolations.size() );
assertEquals( "must not be null", constraintViolations.iterator().next().getMessage() );

Bean Validation constraints

Hibernate Validator 6.0.22.Final - JSR 380 Reference Implementation: Reference Guide

Declaring and validating method constraints

Declaring method constraints

Parameter constraints

package org.hibernate.validator.referenceguide.chapter03.parameter;

public class RentalStation {

    public RentalStation(@NotNull String name) {
        //...
    }

    public void rentCar(
            @NotNull Customer customer,
            @NotNull @Future Date startDate,
            @Min(1) int durationInDays) {
        //...
    }
}

Cross-parameter constraints

n order to define a cross-parameter constraint, its validator class must be annotated with @SupportedValidationTarget(ValidationTarget.PARAMETERS). The type parameter T from the ConstraintValidator interface must resolve to either Object or Object[] in order to receive the array of method/constructor arguments in the isValid() method.

package org.hibernate.validator.referenceguide.chapter03.crossparameter;

public class Car {

    @LuggageCountMatchesPassengerCount(piecesOfLuggagePerPassenger = 2)
    public void load(List<Person> passengers, List<PieceOfLuggage> luggage) {
        //...
    }
}

package org.hibernate.validator.referenceguide.chapter06.crossparameter;

@Constraint(validatedBy = ConsistentDateParametersValidator.class)
@Target({ METHOD, CONSTRUCTOR, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Documented
public @interface ConsistentDateParameters {

    String message() default "{org.hibernate.validator.referenceguide.chapter04." +
            "crossparameter.ConsistentDateParameters.message}";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
}

package org.hibernate.validator.referenceguide.chapter06.crossparameter;

@SupportedValidationTarget(ValidationTarget.PARAMETERS)
public class ConsistentDateParametersValidator implements
        ConstraintValidator<ConsistentDateParameters, Object[]> {

    @Override
    public void initialize(ConsistentDateParameters constraintAnnotation) {
    }

    @Override
    public boolean isValid(Object[] value, ConstraintValidatorContext context) {
        if ( value.length != 2 ) {
            throw new IllegalArgumentException( "Illegal method signature" );
        }

        //leave null-checking to @NotNull on individual parameters
        if ( value[0] == null || value[1] == null ) {
            return true;
        }

        if ( !( value[0] instanceof Date ) || !( value[1] instanceof Date ) ) {
            throw new IllegalArgumentException(
                    "Illegal method signature, expected two " +
                            "parameters of type Date."
            );
        }

        return ( (Date) value[0] ).before( (Date) value[1] );
    }
}
package org.hibernate.validator.referenceguide.chapter03.parameterscriptassert;

public class Car {

    @ParameterScriptAssert(lang = "javascript", script = "luggage.size() <= passengers.size() * 2")
    public void load(List<Person> passengers, List<PieceOfLuggage> luggage) {
        //...
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值