Introduction to hibernate validator
In the early web sites, users input an email address and need to send the email address to the server. The server verifies it and sends a response to the front end after the verification is successful.
With JavaScript, the verification work can be performed on the front end. So why do you need to check the server? Because the data from the front end is not trusted. The front end can easily get the interface of the back end. If someone calls the interface directly, illegal data may appear, so the server also needs data verification.
in general:
- Front end verification: mainly to improve user experience
- Back end verification: mainly to ensure the safety and reliability of data
Verifying parameters is basically a manual job, and there are many redundant codes, which also affect the readability of the code. We need a more elegant way to solve this problem. Hibernate Validator framework just solves this problem. It can realize parameter verification in a very elegant way, separate business code from verification logic, and no longer write duplicate verification logic.
Hibernate validator advantages:
- The verification logic is separated from the business logic, which reduces the coupling degree of the program
- Unified and standardized verification method, no need for you to write repeated verification code again
- You will focus more on your business and leave all these cumbersome things aside
maven coordinates of Hibernate validator:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.18.Final</version> </dependency>
Hibernate validator common annotations
The verification method provided by hibernate validator is to add corresponding annotations to the attributes of classes to achieve the purpose of verification. The comments provided by hibernate validator for verification are as follows:
annotation | explain |
---|---|
@AssertTrue | Used for boolean field, which can only be true |
@AssertFalse | Used for boolean field, which can only be false |
@CreditCardNumber | Carry out a general verification of the credit card number |
@DecimalMax | Can only be less than or equal to this value |
@DecimalMin | Can only be greater than or equal to this value |
Check whether it is a valid email address | |
@Future | Check whether the date of this field belongs to the future date |
@Length(min=,max=) | Check whether the length of the field is between min and max, which can only be used for strings |
@Max | The value of this field can only be less than or equal to this value |
@Min | The value of this field can only be greater than or equal to this value |
@NotNull | Cannot be null |
@NotBlank | Cannot be empty, spaces will be ignored when checking |
@NotEmpty | Cannot be empty, where null refers to an empty string |
@Pattern(regex=) | The annotated element must conform to the specified regular expression |
@URL(protocol=,host,port) | Check whether it is a valid URL. If protocol, host, etc. are provided, the URL also needs to meet the conditions provided |
Introduction case of Hibernate validator
Step 1: create maven project hibernate validator_ Demo and configure pom XML file
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> <relativePath/> </parent> <groupId>cn.itcast</groupId> <artifactId>hibernate-validator_demo</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- spring-boot-starter-web Has been dependent on hibernate-validator --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.18.Final</version> </dependency> --> </dependencies> </project>
Note: spring boot starter web already relies on Hibernate validator, so there is no need to import it again.
Step 2: create User class
package cn.itcast.entity; import lombok.Data; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.*; @Data public class User { @NotNull(message = "user id Cannot be empty") private Integer id; @NotEmpty(message = "User name cannot be empty") @Length(max = 50, message = "User name length cannot exceed 50") private String username; @Max(value = 80,message = "The maximum age is 80") @Min(value = 18,message = "The minimum age is 18") private int age; @Pattern(regexp = "[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$", message = "Email format is incorrect") private String email; }
Step 3: create UserController
package cn.itcast.controller; import cn.itcast.entity.User; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.validation.constraints.NotBlank; @RestController @RequestMapping("/user") @Validated //Enable the verification function public class UserController { //Simple data type verification @RequestMapping("/delete") public String delete(@NotBlank(message = "id Cannot be empty") String id){ System.out.println("delete..." + id); return "OK"; } //Object attribute verification @RequestMapping("/save") public String save(@Validated User user){ System.out.println("save..." + user); return "OK"; } }
Step 4: create application yml
server: port: 9100
Step 5: create a startup class
package cn.itcast; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class HibernateValidatorApp { public static void main(String[] args) { SpringApplication.run(HibernateValidatorApp.class,args); } }
Start the project, access address: http://localhost:9100/user/save Through the console output, you can see that the data can be verified, as follows:
Field error in object 'user' on field 'age': rejected value [3]; codes [Min.user.age,Min.age,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.age,age]; arguments []; default message [age],18]; default message [The minimum age is 18]] 2020-03-02 16:44:35.504 WARN 14896 --- [nio-9100-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 3 errors Field error in object 'user' on field 'id': rejected value [null]; codes [NotNull.user.id,NotNull.id,NotNull.java.lang.Integer,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.id,id]; arguments []; default message [id]]; default message [user id Cannot be empty] Field error in object 'user' on field 'age': rejected value [0]; codes [Min.user.age,Min.age,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.age,age]; arguments []; default message [age],18]; default message [The minimum age is 18] Field error in object 'user' on field 'username': rejected value [null]; codes [NotEmpty.user.username,NotEmpty.username,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.username,username]; arguments []; default message [username]]; default message [User name cannot be empty]]
The browser page directly reports an error:
Step 6: in order to display the data verification results friendly on the page, you can solve it through global exception handling and create a global exception handling class
package cn.itcast.config; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Controller; import org.springframework.validation.BindException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import java.util.Set; /** * Global exception handling */ @ControllerAdvice(annotations = {RestController.class, Controller.class}) @ResponseBody public class ExceptionConfiguration { @ExceptionHandler({ConstraintViolationException.class,BindException.class}) public String validateException(Exception ex, HttpServletRequest request) { ex.printStackTrace(); String msg = null; if(ex instanceof ConstraintViolationException){ ConstraintViolationException constraintViolationException = (ConstraintViolationException)ex; Set<ConstraintViolation<?>> violations = constraintViolationException.getConstraintViolations(); ConstraintViolation<?> next = violations.iterator().next(); msg = next.getMessage(); }else if(ex instanceof BindException){ BindException bindException = (BindException)ex; msg = bindException.getBindingResult().getFieldError().getDefaultMessage(); } return msg; } }
Restart the program to find that the verification information can be displayed on the page friendly at this time:
From the output of the console, we can see that the verification framework has performed data verification on many of our attributes (the default behavior). If we want to return a prompt directly as long as one attribute fails to verify, how can we implement it if the following attributes are no longer verified?
Step 7: create a ValidatorConfiguration class, and specify the fast failure return mode to be used during verification
package cn.itcast.config; import org.hibernate.validator.HibernateValidator; import org.springframework.context.annotation.Bean; import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; public class ValidatorConfiguration { @Bean public Validator validator() { ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class) .configure() //Quick failure return mode .addProperty("hibernate.validator.fail_fast", "true") .buildValidatorFactory(); return validatorFactory.getValidator(); } /** * Enable quick return * If there is an exception in the parameter verification, throw the exception directly, and do not enter the controller. Use global exception interception to intercept */ @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor(); /**Set the validator mode to fast failure return*/ postProcessor.setValidator(validator()); return postProcessor; } }
Note: the class created above is not a configuration class, so the quick failure return mode will not take effect so far. In order to make it take effect, you need to create an annotation to control the opening of this mode
Step 8: create an annotation EnableFormValidator to control the opening of the quick failure return mode
package cn.itcast.config; import org.springframework.context.annotation.Import; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Add this annotation on the startup class to start the form verification function - quick failure return mode */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Import(ValidatorConfiguration.class) public @interface EnableFormValidator { }
Step 9: add the EnableFormValidator annotation to the startup class to enable the quick failure return mode
package cn.itcast; import cn.itcast.config.EnableFormValidator; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableFormValidator public class HibernateValidatorApp { public static void main(String[] args) { SpringApplication.run(HibernateValidatorApp.class,args); } }
From the output of the console, we can see that although many of the data we entered do not conform to the verification rules, there is only one verification failure exception message, which indicates that the rapid failure return mode has been enabled.