“This is the 13th day of my participation in the First Challenge 2022. For details: First Challenge 2022”

Data verification is a very common operation in the development process. The common practice is:

public boolean addUser(StudentJson json){
    if(json.getFirstName() == null || "".equals(json.getFirstName().trim())){
        throw new IllegalArgumentException("Name cannot be empty");
    }
    // Other verification logic
    return true;
}
Copy the code

Write all the validation logic in the business code. One other problem that might exist here is that one type of data might have essentially the same validation logic and just null it. If there is no uniform interface specification for handling validation. This requires the user to write validation logic for the fields of different beans. Bean Validation solves this problem. The most widely used implementation of Bean Validation is hibernate-Validator. Spring, for example, uses hibernate-Validator.

Hibernate – Validator Github address: github.com/hibernate//…

Constrain once, Validate Everywhere

The knowledge structure diagram of Bean Validation is as follows:

How to customize a constraint, step by step, according to the knowledge structure diagram of Bean Validation above. A mobile number constraint is defined below

1. Define constraints

The annotation constraints defined are as follows:

@Documented @Constraint(validatedBy = MobileNumValidator.class) @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE }) @Retention(RetentionPolicy.RUNTIME) public @interface MobileNum { String message() default "{com.github.mxsm.MobileNum.message}"; Class<? >[] groups() default { }; Class<? extends Payload>[] payload() default { }; }Copy the code

Label 1: the @constraint annotation sets up a custom validator. MobileNumValidator needs to implement its own ConstraintValidator interface

Label 2: These are the three attributes that are mandatory for the constraint (additional attributes can also be added)

Message insertion value defined by default in ValidationMessages. The properties file, here also involves the internationalization and so on.

2. ConstraintValidator interface implementation

The MobileNumValidator interface is as follows:

public class MobileNumValidator implements ConstraintValidator<MobileNum.String> {

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {

        if(null== value || value.trim().length() ! =11| |! value.matches("^ [0-9] + $")) {return false;
        }
        return true; }}Copy the code

3. MobileNum annotation test

The test code is as follows:

public class ValidationMain {

    public static void main(String[] args) {
        Person person = new Person();
        person.setMobile("122222222");
        Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
        Set<ConstraintViolation<Person>> constraintViolations = validator.validate( person );
        ConstraintViolation<Person> next = constraintViolations.iterator().next();
        String message = next.getMessage();
        System.out.println(message);
    }


    public static class Person{
        @MobileNum
        //@Email
        private String mobile;

        public String getMobile(a) {
            return mobile;
        }

        public void setMobile(String mobile) {
            this.mobile = mobile; }}}Copy the code

Add maven dependencies for Hibernate-Validator.

    <dependency>
      <groupId>jakarta.validation</groupId>
      <artifactId>jakarta.validation-api</artifactId>
      <version>3.0.1</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>7.0.2. The Final</version>
    </dependency>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>jakarta.el</artifactId>
      <version>4.0.1</version>
    </dependency>
Copy the code

Also need to increase the Jakarta. Validation – API, because high version of the JavaEE have not javax.mail here in Jakarta, need pay attention to the following at the same time create a ValidationMessages under classpath. The properties files

com.github.mxsm.MobileNum.message=The mobile number is incorrect
Copy the code

Run to view the result:

Can see from the result of running successful printed in ValidationMessages. The configuration of the properties of cellular phone number is not correct

4. To summarize

  • Custom Constraint annotations need to be decorated with @constraint and must contain three attributes: message, groups, and Payload
  • Messages for custom annotations generally use placeholders to facilitate possible internationalization later
  • Hibernate-validatorThe default read isValidationMessages.propertiesIf the internationalized configuration file format is validationMessages_XXXX. properties, for example:ValidationMessages_en_US.propertiesGet the LOCALE of the JVM (locale #getDefault())

References:

  • Hibernate.org/validator/r…
  • beanvalidation.org/