Using hibernate validator as a data validation component in Spring

Keywords: Java Hibernate Spring Attribute Web Development

In the process of web development, it is often necessary to verify the data sent by the client to prevent the data from being illegal.

Spring MVC supports data validation as JSR303 standard, which is verified by annotation @NotNull @Max and other annotations on bean properties. JSR303 provides many annotation excuses, and spring MVC uses hibernate for these validations, so we need to add a validator package of Hibernate:

Introducing in spring MVC

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.18.Final</version>
</dependency>

Introducing in spring boot

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

hibernate provides additional validation annotations in addition to the JSR 303 standard. The following table is the validation notes supported by JSR303:

Constraint annotation name Constraint notes
@Null Verify that the object is empty
@NotNull Verify that the object is not empty
@AssertTrue Verify that the Boolean object is true
@AssertFalse Verify that the Boolean object is false
@Min Verify that the Number and String objects are large equal to the specified value
@Max Verify that the Number and String objects are small equal to the specified value
@DecimalMin Verify whether the Number and String objects are large equal to the specified value, and the decimal has precision
@DecimalMax Verify whether the Number and String objects are small equal to the specified value, and the decimal has precision
@Size Check whether the length of array, collection, map, string is within the given range
@Digits Verify that Number and String are valid
@Past Verify that the Date and Calendar objects are before the current time
@Future Verify that the Date and Calendar objects are after the current time
@Pattern Verify that the String object conforms to the regular expression rules

Additional notes for Hibernate Validator:

annotation detailed information
@Email Must be email address
@Length The size of the commented string must be within the specified range
@NotEmpty The annotated string must be non empty
@Range The annotated element must be within the specified range

Let's write a small demo to show how to use it. For example, if I want to verify that some fields cannot be empty, I can use @ NotNull annotation, as shown in the following example:

package org.zero01.test;

import javax.validation.constraints.NotNull;

public class UserRegister {

    @NotNull(message = "User name cannot be empty")
    private String userName;
    @NotNull(message = "Password cannot be empty")
    private String password;
    @NotNull(message = "Contact address cannot be empty")
    private String address;
    @NotNull(message = "Phone number cannot be empty")
    private String phone;
    ...getter and setter...

In the method parameters of the controller, you need to declare the BindingResult parameter to get the validation error information, and then use the @ Valid annotation to configure which pojo object needs to be verified. The controller code is as follows:

package org.zero01.test;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.validation.Valid;

@Controller
public class Test {

    @RequestMapping(value = "/test.do", method = RequestMethod.GET)
    // Note that @ Valid and BindingResult are paired, and the parameter order is fixed (one before and one after). Otherwise, 400 status code will be returned
    public String test(@Valid UserRegister userRegister, BindingResult bindingResult, Model model) {
        // Judge whether there is abnormality
        if (bindingResult.hasErrors()) {
            System.out.println("The request data of the client is abnormal. All exceptions are as follows:");
            // Take out all exception objects
            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                // Print exception fields and exception information
                System.out.println(fieldError.getField() + " : " + fieldError.getDefaultMessage());
            }
            return "register";
        }
        return "index";
    }
}

Use Postman to access without writing any parameters

The console output is as follows:

The request data of the client is abnormal. All exceptions are as follows:
Address: contact address cannot be empty
 userName: user name cannot be empty
 Password: password cannot be empty
 Phone: phone number cannot be empty

Here are some other common annotations:

package org.zero01.test;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

public class UserRegister {

    @NotNull(message = "User name cannot be empty")
    private String userName;

    @NotNull(message = "Password cannot be empty")
    @Length(max = 12, min = 6, message = "Password length should be 6-12 Between bits")
    private String password;

    @NotNull(message = "Contact address cannot be empty")
    private String address;

    @NotNull(message = "Phone number cannot be empty")
    // Specify regular expression validation format
    @Pattern(regexp = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\\\d{8}$", message = "Phone number format error")
    private String phone;

    @Email(message = "Mailbox format error")
    private String email;

    @Size(max = 10, min = 1, message = "The length of the report card list should be 1-10 Between")
    public List resultList;
    ...getter and setter...

The controller code is the same as before, omitted.

Using Postman for access

The console output is as follows:

The request data of the client is abnormal. All exceptions are as follows:
Address: contact address cannot be empty
 userName: user name cannot be empty
 Password: the password length should be between 6-12 digits
 Phone: phone number format error
 Email: email format error
 resultList: the length of transcript list should be between 1-10

All the above fields are verified. What if I want some fields not to be verified or verified separately? At this time, we need to verify the grouping. First, write an interface:

package org.zero01.test;

public interface Group {
}

Then add the groups attribute to the annotation of the field to be grouped. The value of the attribute is the interface class defined above, as shown in the following example:

package org.zero01.test;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

public class UserRegister {

    // The groups property is used to specify a group. The value is an interface class
    @NotNull(message = "User name cannot be empty", groups = Group.class)
    private String userName;

    @NotNull(message = "Password cannot be empty", groups = Group.class)
    @Length(max = 12, min = 6, message = "Password length should be 6-12 Between bits", groups = Group.class)
    private String password;

    @NotNull(message = "Contact address cannot be empty")
    private String address;

    @NotNull(message = "Phone number cannot be empty")
    @Pattern(regexp = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\\\d{8}$", message = "Phone number format error")
    private String phone;

    @Email(message = "Mailbox format error")
    private String email;
    ...getter and setter...

The controller code is as follows:

package org.zero01.test;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.validation.Valid;

@Controller
public class Test {

    @RequestMapping(value = "/test.do", method = RequestMethod.GET)
    // In the case of grouping, you need to use the Validated annotation to specify the interface
    public String test(@Validated(Group.class) UserRegister userRegister, BindingResult bindingResult, Model model) {

        if (bindingResult.hasErrors()) {
            System.out.println("The request data of the client is abnormal. All exceptions are as follows:");

            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                System.out.println(fieldError.getField() + " : " + fieldError.getDefaultMessage());
            }
            return "register";
        }
        return "index";
    }
}

The access method is the same as before, omitted.

The console output is as follows:

The request data of the client is abnormal. All exceptions are as follows:
Password: the password length should be between 6-12 digits
 userName: user name cannot be empty

As mentioned above, from the printed results of the console, you can see that only two fields, password and userName, have been verified, because we only specified the groups property in the comments on these two fields. So group verification is to verify only the fields of the specified group, and the division of this group is based on the interface.

Standing on the shoulders of giants picking apples:

https://blog.51cto.com/zero01/2090999

Posted by Liquid Fire on Sat, 07 Mar 2020 23:50:51 -0800