Java Bean Annotation Constraint Validation 未完待续

边学边用,有问题欢迎指出。


Chapter 1. 简单的 Annotation Constraint 的使用

package tutorial.chapter01;

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;
	
	
	public Car(String manufacturer, String licencePlate, int seatCount) {
		this.manufacturer = manufacturer;
		this.licensePlate = licencePlate;
		this.seatCount = seatCount;
	}
}

以上的代码片段,我们应用annotation 来限制 

1.  `manufacturer`不为 null

2. `licensePlate` string的长度在 2-14之间

3. ·seaCount· 的值最小为2


使用一下代码片段来检验

package tutorial.chapter01;

import java.util.Set;

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

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

import static org.junit.Assert.assertEquals;

public class CarTest {
	private static Validator validator;
	
	@BeforeClass
    public static void setUp() {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        validator = factory.getValidator();
    }

    @Test
    public void manufacturerIsNull() {
        Car car = new Car( null, "DD-AB-123", 4 );

        Set<ConstraintViolation<Car>> constraintViolations =
                validator.validate( car );
	//这里我们故意将manufacture 设成 null, 其他项是正确的,我们将返回一个相对应的violation
        assertEquals( 1, constraintViolations.size() );
        assertEquals( "may not be null", constraintViolations.iterator().next().getMessage() );
    }

    @Test
    public void licensePlateTooShort() {
        Car car = new Car( "Morris", "D", 4 );

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

        assertEquals( 1, constraintViolations.size() );
        assertEquals(
                "size must be between 2 and 14",
                constraintViolations.iterator().next().getMessage()
        );
    }

    @Test
    public void seatCountTooLow() {
        Car car = new Car( "Morris", "DD-AB-123", 1 );

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

        assertEquals( 1, constraintViolations.size() );
        assertEquals(
                "must be greater than or equal to 2",
                constraintViolations.iterator().next().getMessage()
        );
    }

    @Test
    public void carIsValid() {
        Car car = new Car( "Morris", "DD-AB-123", 2 );

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

        assertEquals( 0, constraintViolations.size() );
    }
}

当我们使用 annotation的时候, 编译并执行的时候并不会给我们的限制进行检验,想要检验我们的变量是否满足我们的annotation的限制的时候我们需要使用`ValidatorFactory` 来创建一个 Validator instance. Validator.validate() 方法将会返回 a set of ConstraintViolation.  我们就可以通过观察 这个set来看看我们哪个 变量不符合限制。


Chapter 2. 


不同等级的 annotation 

a. 变量级别 :从以下代码片段可以看出,我们对class 的变量使用了annotation。这个chapter 1的例子是一样的。

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


b. 方法级别: 以下 的作用和以上是一样的,因为当我们 对方法进行限制的时候我们实际上是对它的 返回类型进行限制。

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

c. class 级别: 这个是对整个的类的内容进行限制,需要我们自己根据需求进行定制。 以后会提到,先从基础来。


d. 因为不同级别的annotation,我们就会问那夫类和子类之间的继承或者接口是怎么处理的。很好的问题,其实也很简单,那就是无论是继承还是实现我们都会原封不动的接受得到的限制。但是! 接收到的限制不一定会表达,例如以下的例子。 如果我们把 @Valid 注释掉,然后我门对Car 进行 validate, 那么 Person 类是不会被 validate的。要想在validate Car的时候也Validate person那我们需要加上@Valid annotation. 


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;

    //...
}


@Valid的作用简单来说就是继续validate 被@Valid 标记的变脸内部的变脸

e.g. 这样的话我们仅仅validate来list是否是 null

@NotNull
List<Person> list;

加上valid 才会继续去validate person内部。

@NotNull
@Valid
List<Person> list;

e. 当得到 constraint violation 之后我门如何通过 ConstraintViolation 的instance来找到我门的violation.

Java Doc - ConstraintViolation 这里是他的方法。我就拿其中一个我觉的有点意思的举个例子. 考虑以下代码,当我们实例化一个valid 的car和person 但是 personname 的age是错的。那当我们得到constraintviolation怎么知道personname的路径在哪里呢? 使用: 

gePropertyPath()

结果是 

driver.personName.age

Class Car {
  @NotNull
  @Valid
  Person person;
  //.....
}

Class  Person {
  @NotNull
  @Valid
  PersonName personName;
  //...
}

Class PersonName {
  @Min(18)
  int age;
}

Chapter 03: 方法的parameter 和 return value 的constraint

这章总结来看,主要介绍了如何给一个方法的paramter 和 return value进行constraint validate. 



猜你喜欢

转载自blog.csdn.net/ytdxyhz/article/details/74025164