Spring boot combined with hibernate validate verification data learning
Hibernate validate data verification dependency has been introduced into the web Start dependency of spring boot. As long as the web Start dependency of the project depends, there is no need to introduce dependency.
Dependency introduction
<dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.1.4.Final</version> </dependency>
Introduction to common notes
validate implements the specified verification functions one by one by adding annotations to the fields. Common annotations are:
annotation | describe |
---|---|
@NotNull | Cannot be empty |
@NotBlank | The string cannot be empty or empty |
@Null | The verified object can only be null |
@Size(min=2,max=6) | The length of the verified string can only be between 2 and 6 |
@Max(value=7) | The maximum verified parameter can only be 7 |
@AssertTrue | The attribute value of the label must be true |
@AssertFalse | The attribute value of a dimension must be false |
@Past | Time must be in the past |
@Future | Future time |
@Pattern | Used to specify a regular expression |
@NotEmpty | String content is not empty |
mailbox | |
@Range | Used to specify numbers. Note that the range of numbers has two values, min and max |
@Digits | Content must be numeric |
@PositiveOrZero | 0 or integer |
Simple use
Using validate to validate data, you can define validation annotations in object fields or method parameters
Define validation annotations in pojo
public class Entity { @NotBlank(message = "User name cannot be empty") private String username; @NotBlank(message = "Password cannot be empty") @Length(min = 6,message="Length must be greater than or equal to 6") //Password length must be greater than six private String password; @Email(message="Illegal email address") private String email; @NotBlank(message = "Mobile phone number cannot be empty") @Length(min = 11, max = 11, message = "Mobile phone number can only be 11 digits") @Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "Wrong mobile phone number format") private String phone; }
Define validation annotations on method parameters
Note that the @ Validated annotation needs to be added to the class name to use the validation annotation on the method parameters
@RestController @RequestMapping("/demo") @Validated //Parameter verification public class DemoController { @PostMapping("/search/{page}/{size}") public Entity demo(@RequestBody @Validated Entity entity, @PathVariable("page") @Min(value = 0) Integer page, @PathVariable("size") @Min(value = 0) Integer size){ System.out.println(entity.getUsername()+"---"+entity.getPassword()); System.out.println(page+"----------"+size); return entity; } }
Unified exception handling
If it is defined on the object field, if it is verified that the data is invalid, the following will be thrown:
MethodArgumentNotValidException extends Exception //Invalid method parameter exception
If it is defined in the method parameter, if the data is invalid, throw:
ConstraintViolationException extends ValidationException //Constraint exception
We can define a global exception handler in spring boot to intercept the prompt information returned after an exception occurs in the verification
/** * Global exception handler */ @ControllerAdvice public class ExceptionGlobalHandler { @ExceptionHandler(Exception.class) @ResponseBody public Result handle(Exception e){ //System.out.println(e); String message = null; if(e instanceof MethodArgumentNotValidException){ //Parameter verification - object data verification exception //get prompting information for (ObjectError error : ((MethodArgumentNotValidException) e).getBindingResult().getAllErrors()) { message = error.getDefaultMessage();//Get custom error message } }else if(e instanceof ConstraintViolationException){ //Method parameter verification exception Iterator<ConstraintViolation<?>> iterator = ((ConstraintViolationException) e).getConstraintViolations().iterator(); ConstraintViolation<?> next = iterator.next(); message = next.getMessage(); //Get custom error message }else{ message = e.getMessage(); //Other exceptions } return Result.error().setMessage(message); } }
Extension 1: Group verification
When using hibernate validate for data verification, we sometimes verify the data by situation. For example, when adding, we do not verify that the id is not empty, but when modifying, we need to verify that the id is not empty. If @ NotNull is used for verification, null verification will also be performed during insert operation, which is not what we want. At this time, we can group the verification and use different groups for data verification under different circumstances.
Each group needs an interface as the flag of the group, but no content can be added in the interface
General grouping includes: add insert; Modify ipdate; delete; Query select
I use internal interfaces to manage these tag class interfaces
public class ValidateGroupFalg { /** * Add operation group */ public static interface InsertFlag{} /** * Delete action group */ public static interface DeleteFlag{} /** * Modify operation group */ public static interface UpdateFlag{} /** * Query operation group */ public static interface SelectFlag{} }
For the verification user id, group verification is performed
@TableName("tb_demo") public class TbDemo implements Serializable { @TableId(type = IdType.INPUT) @NotNull(message = "Please specify the number to modify",groups = ValidateGroupFalg.UpdateFlag.class) private String id; }
When using, you only need to add verification annotation and specify grouping mark in the parameters of the receiving method
public Result updateById(@RequestBody @Validated(ValidateGroupFalg.UpdateFlag.class) TbDemo tbDemo){ // .... }
Extension 1: user defined verification
When we need to perform some specified verifications, we can create custom verifications through the AIP provided by hibernate validator.
step
1. Create annotations and specify data processing classes
2. Create a data processing class to implement internal methods
3. Using annotations
realization
1. Create annotations and specify data processing classes
/** * Time string format verification annotation */ @Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = DateTimeValidator.class) //Used to specify the data processing class public @interface DateFormatValidate { String message() default "Time format error"; String format() default "yyyy-MM-dd"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
2. Create a data processing class to implement internal methods
import com.bishe.common.validate.DateFormatValidate; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.text.SimpleDateFormat; /** * Time string format verification */ public class DateTimeValidator implements ConstraintValidator<DateFormatValidate, String> { private DateFormatValidate dateFormatValidate ; //Annotation reference public void initialize(DateFormatValidate constraint) { this.dateFormatValidate = constraint; //System.out.println("initialization method call...); } //The verification method returns true successfully; If it fails, false will be returned. Validate will judge and false will throw an exception public boolean isValid(String value, ConstraintValidatorContext context) { //System.out.println("start verification...); if (value == null) { return true; } String format = dateFormatValidate.format(); //Get custom time format if (value.length() != format.length()) { //If the length of 2020-10-10 is different from yyyy MM DD, false is returned return false; } try { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); //Create time format object simpleDateFormat.parse(value); //An attempt is made to convert the verified parameters by format. A success is returned as true. A failure is returned as false } catch (Exception e){ return false; //Conversion failed } return true; //Verification successful } }
3. Using annotations
@DateFormatValidate(format = "yyyy/MM/dd", message = "Format error, correct format is: yyyy/MM/dd") private Date birthday;
Done!