Deep understanding of data validation: Java Bean Validation 2.0 (JSR380)

Keywords: Programming Hibernate Bean Validation Java Apache

We know that programs are usually hierarchical, and different layers are usually developed by different people. If you're an experienced programmer, I'm sure you've seen the same validation code in different layers, which is spam code in a sense. To solve this problem, Bean Validation defines the corresponding metadata model and API for JavaBean validation. The default metadata is all kinds of Java Annotations, and of course supports xml mode, and you can also extend ~Bean Validation is an extension of JavaBean, it can be laid out in any layer of code, not limited to Web applications or end applications.

Java Bean Validation

JSR is the abbreviation of Java Specification Requests, which means Java Specification Proposal. About data validation, the latest is JSR380, which is JSR 380 standard. Bean Validation is a framework for validating parameters by configuring annotations. It consists of two parts: Bean Validation API (specification) and Hibernate Validator (implementation).

 

Simple Demo Example

  1. The minimum version requirement for Java is Java 8
  2. Supports container validation and constraints on container content through annotations of TYPE_USE type: `List< @Email String>`
  3. Support date/time verification. @Past and @Future
  4. Expanding metadata (new annotations): @Email ,@NotEmpty,@NotBlank,@Positive,@PositiveOrZero,@Negative,@NegativeOrZero,@PastOrPresent and@FutureOrPresent
    1. Like @Email, @NotEmpty, @NotBlank, which was previously provided by Hibernate, hibernate abdicated automatically after 2.0 and was marked as expired.
  5. The only implementation of Bean Validation 2.0 is Hibernate Validator. (Actually, there's Apache BVal, but you know, forget it)
  6. For Hibernate Validator, it also extends some annotation support.

So, there's no good choice for Java Bean Validation implementation landing products. Import Hibernate Validator (the latest version):

  • POM Accession
       <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.20</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.0.17.Final</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-el</artifactId>
            <version>8.5.29</version>
            <!--<scope>provided</scope> This is the best way to pack. scope-->
        </dependency>
  • Write a Java Bean
@Getter
@Setter
@ToString
public class Person {

    // Error message can be customized
    @NotNull(message = "Name cannot be null")
    public String name;
    @Positive
    public Integer age;

    @NotNull
    @NotEmpty
    private List<@Email String> emails;
    @Future
    private Date start;

}
 public static void main(String[] args) {
        Person person = new Person();
        //person.setName("fsx");
        person.setAge(-1);
        // email Check: Although List can be checked
        person.setEmails(Arrays.asList("fsx@gmail.com", "baidu@baidu.com", "aaa.com"));
        //Person.setStart (new Date (); //start needs to be a future time: Sun Jul 21 10:45:03 CST 2019
        //Person. setStart (new Date (System. current Time Millis () + 10000); // Checkout passed

        // Checking the person and getting the result (obviously using the default checker) retains the message that the check failed.
        Set<ConstraintViolation<Person>> result = Validation.buildDefaultValidatorFactory().getValidator().validate(person);
        // Ergodic output of results
        result.stream().map(v -> v.getPropertyPath() + " " + v.getMessage() + ": " + v.getInvalidValue())
                .forEach(System.out::println);


       //Using hibernate Validator
        HibernateValidatorConfiguration configuration = Validation.byProvider(HibernateValidator.class)
				 .configure()
				 .failFast(false);
		 ValidatorFactory validatorFactory = configuration.buildValidatorFactory();

		 Set<ConstraintViolation<TestBean>> sets= validatorFactory.getValidator().validate(person);

		 sets.stream().map(v->v.getPropertyPath()+" " +v.getMessage()+":"+v.getInvalidValue()).forEach(System.out::println);
    }
  • Run the mian function, and the console prints the output
Name name cannot be null: null // where the error message is your own custom content
age must be positive: -1
Emails [2]. < list element > is not a valid e-mail address: aaa.com

Common validation rules are as follows:

@ AssertFalse verifies that boolean type can only be false
@ AssertTrue verifies that boolean types can only be true

Other rules can be found in detail:

Under the javax.validation.constraints package

Core API Analysis

Validation class

The official definition is: This class is the entry point for Bean Validation. As the entry point for verification, it has three ways to start. Here we mainly look at the most common way to start:

  • The simplest way is to use the default ValidatorFactory = Validation. buildDefaultValidatorFactory ();
  • You can directly provide a type-safe Validation Provider implementation. Hibernate Validator, for example, is a Validation Provider implementation:
    HibernateValidatorConfiguration configuration = Validation.byProvider(HibernateValidator.class)
            // ProvderResolver (...)// / Because Provider is in place, this parameter is optional.
            .configure()
            .failFast(false);
    ValidatorFactory validatorFactory = configuration.buildValidatorFactory();
    

     

Posted by skypilot on Tue, 23 Jul 2019 23:52:49 -0700