Use hibernate validator to complete parameter verification before entering the controller

Posted by binarynomad on Sat, 26 Feb 2022 16:52:02 +0100

1, Why use validator?

Parameter verification is a very important step in the development process. If the front-end parameter verification is for user experience, the back-end parameter verification is for security.
Have you ever done parameter verification? Judge one field by one. The disadvantages of this approach are obvious - code redundancy, which I have done before.
Later, I found that there are ready-made validator tools through learning. Why not use them directly?

2, Use steps of Hibernate validator

2.1 define controller global exception handler

When using validator for parameter verification, exceptions will be thrown for unqualified parameters.
If not handled, the exception will be thrown to the front end and become useless. To handle exceptions gracefully,
We need to define the global controller exception handler.
ControllerExceptionHandler

@RestControllerAdvice
@Slf4j
public class ControllerExceptionHandler {
	@ExceptionHandler(Exception.class)
	public Result<?> handleException(Exception e){
		log.error(e.getMessage(), e);
		return Result.error(e.getMessage());
	}
}

2.2 define, add and update validators

  • InsertValidator: the corresponding field validation takes effect when adding

  • UpdateValidator: the corresponding field validation takes effect when updating

    InsertValidator

/**
 * Add verifier
 *
 */
public interface InsertValidator {

}

UpdateValidator

/**
 * Edit validator
 *
 */
public interface UpdateValidator {

}

2.3 add verification conditions to entity classes

JSR 303 is only a specification and has no specific implementation. At present, hibernate validator usually performs unified parameter verification.

Basic verification type defined by JSR303:

  • @Null the annotated element must be null
  • @NotNull the annotated element must not be null
  • @AssertTrue the annotated element must be true
  • @AssertFalse the annotated element must be false
  • @Min(value) the annotated element must be a number and its value must be greater than or equal to the specified minimum value
  • @Max(value) the annotated element must be a number whose value must be less than or equal to the specified maximum value
  • @DecimalMin(value) the annotated element must be a number whose value must be greater than or equal to the specified minimum value
  • @DecimalMax(value) the annotated element must be a number whose value must be less than or equal to the specified - maximum value
  • @Size(max, min) the size of the annotated element must be within the specified range
  • @Digits (integer, fraction) the annotated element must be a number and its value must be within an acceptable range
  • @Past annotated element must be a past date
  • @Future the annotated element must be a future date
  • @Pattern(value) the annotated element must conform to the specified regular expression

Additional constraint s in Hibernate Validator:

  • @The annotated element of Email must be an Email address
  • @Length the size of the annotated string must be within the specified range
  • @NotEmpty the of the annotated string must be non empty
  • @Range the annotated element must be within the appropriate range
@Data
public class User {


    @NotNull(groups = { UpdateValidator.class })
    private Long id;// ID
    /**
     * Verification conditions take effect when adding
     * The user name cannot be empty, and the number of user names is between 1-20.
     * */
    @NotEmpty(message = "username Required",groups = { InsertValidator.class })
    @Size(max = 20, min = 1,message = "The number of user names is 1-20 between", groups = { InsertValidator.class })
    private String username;// user name

    @NotBlank(message = "Password is required",groups = { InsertValidator.class })
    @Size(min = 6,message = "The number of passwords shall not be less than six", groups = { InsertValidator.class })
    private String password;// password

    /**
     * Verification conditions take effect when adding
     * Mailbox verification rules
     * */
    @NotBlank(message = "Mailbox cannot be empty",groups = { InsertValidator.class })
    @Email(groups = { InsertValidator.class })
    @Size(max = 30,message = "No more than 30 mailboxes", groups = { InsertValidator.class })
    private String email;// mailbox

    /**
     * Verification conditions take effect when adding
     * Mobile number verification rules are used
     * */
    @NotBlank(message = "Mobile phone number cannot be empty",groups = { InsertValidator.class })
    @TelephoneNumber(groups = { InsertValidator.class },message = "Incorrect mobile phone number")
    @Size(max = 20, groups = { InsertValidator.class })
    private String mobile;// cell-phone number

    @Size(max = 20, min = 6, groups = {InsertValidator.class, UpdateValidator.class })
    private String provinceRegionCode;// Province region code

    @Size(max = 20, min = 6, groups = { UpdateValidator.class })
    private String cityRegionCode;// City area code

    @Size(max = 40, groups = { UpdateValidator.class })
    private String address;// Street address

    @Size(max = 256, groups = { UpdateValidator.class })
    private String profile;// Personal profile

}

2.4 add comments in controller

  • @Validated(InsertValidator.class): the properties of InsertValidator used in all group s are validated
  • @Validated(UpdateValidator.class): the properties of all group s that use UpdateValidator are validated
@RestController
@RequestMapping("/user")
public class UserController {
    /**
     * Registered user
     *
     * @param user User details
     * @return
     */
    @PostMapping(path = "/insertUser")
    public void insertUser(@Validated(InsertValidator.class) @RequestBody User user) {
        System.out.println("user = " + user);
    }

    /**
     * Edit user details
     *
     * @param user User details
     * @return
     */
    @PostMapping(path = "/updateUser")
    public void updateUser(@Validated(UpdateValidator.class) @RequestBody User user) {
        System.out.println("user = " + user);
    }

    /**
     * Modify user password
     *
     * @param password    Original password
     * @param newPassword New password
     * @param id          User ID
     * @return
     */
    @PutMapping(path = "/updatePassword")
    public void updatePassword(@RequestParam(name = "password", required = true) String password,
                               @RequestParam(name = "newPassword", required = true) String newPassword,
                               @RequestParam(name = "id", required = true) Long id) {

    }

}

2.5 test results

2.5.1 insert operation

  1. username verification

When the input parameter name is empty

{
  "id": 1,
  "username": "",
  "password": "demoData",
  "email": "1234@qq.com",
  "mobile": "18898987878",
  "provinceRegionCode": "demoData",
  "cityRegionCode": "demoData",
  "address": "demoData",
  "profile": "demoData"
}

result

{
    "success": false,
    "message": "username Required; The number of user names is 1-20 between",
    "code": 400,
    "result": null,
    "timestamp": 1645888982098
}
  1. password verification

1. When the password is empty

{
  "id": 1,
  "username": "Xiao Ming",
  "password": "",
  "email": "1234@qq.com",
  "mobile": "18898987878",
  "provinceRegionCode": "demoData",
  "cityRegionCode": "demoData",
  "address": "demoData",
  "profile": "demoData"
}

result

{
    "success": false,
    "message": "The number of passwords shall not be less than six; Password is required",
    "code": 400,
    "result": null,
    "timestamp": 1645889419709
}

2. When the number of passwords is less than six

{
  "id": 1,
  "username": "Xiao Ming",
  "password": "123",
  "email": "1234@qq.com",
  "mobile": "18898987878",
  "provinceRegionCode": "demoData",
  "cityRegionCode": "demoData",
  "address": "demoData",
  "profile": "demoData"
}

result

{
    "success": false,
    "message": "The number of passwords shall not be less than six",
    "code": 400,
    "result": null,
    "timestamp": 1645889483465
}
  1. Mailbox verification


1. When the mailbox is empty

{
  "id": 1,
  "username": "Xiao Ming",
  "password": "122223",
  "email": "",
  "mobile": "18898987878",
  "provinceRegionCode": "demoData",
  "cityRegionCode": "demoData",
  "address": "demoData",
  "profile": "demoData"
}

result

{
    "success": false,
    "message": "Mailbox cannot be empty",
    "code": 400,
    "result": null,
    "timestamp": 1645889785044
}

2. When the mailbox does not meet the rules

{
  "id": 1,
  "username": "Xiao Ming",
  "password": "122223",
  "email": "1234",
  "mobile": "18898987878",
  "provinceRegionCode": "demoData",
  "cityRegionCode": "demoData",
  "address": "demoData",
  "profile": "demoData"
}

result

{
    "success": false,
    "message": "Is not a legal email address",
    "code": 400,
    "result": null,
    "timestamp": 1645889864638
}

Topics: Java Hibernate Spring