foreword
One of the annoying things about doing web development is to verify the parameters. Basically, every interface must verify the parameters. For example, some format verification is essential. If there are fewer parameters, it is easy to handle, but if there are too many parameters, there will be a lot of IF ELSE
them in the code, such as the following:
This example just checks for empty parameters. If you need to verify the email format and mobile phone number format verification, the code will be more, so let's introduce validator
the verification parameters through annotations.
What is a Validator
Bean Validation is a set of annotation-based data validation specifications defined by Java. It has been upgraded from version 1.0 of JSR 303 to version 1.1 of JSR 349, and then to version 2.0 of JSR 380 (2.0 was completed in 2017.08). version. It SpringBoot
is already integrated in starter-web
, so there is no need to add other dependencies.
Annotation introduction
validator built-in annotations
annotation | details |
---|---|
@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 whose 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 in the acceptable range |
@Past |
The annotated element must be a date in the past |
@Future |
The annotated element must be a future date |
@Pattern(value) |
The annotated element must match the specified regular expression |
Hibernate Validator additional constraints
annotation | details |
---|---|
@Email |
The annotated element must be an email address |
@Length |
The size of the annotated string must be within the specified range |
@NotEmpty |
The annotated string must be non-empty |
@Range |
The annotated element must be in the appropriate scope |
@NotBlank |
Verify that the string is not null and the length must be greater than 0 |
Note :
- @NotNull applies to any type annotated elements must not be used with NULL
- @NotEmpty is for String Map or array cannot be Null and length must be greater than 0
- @NotBlank can only be used on String and cannot be null. After calling trim(), the length must be greater than 0
use
It's also very simple to use, skip creating a project below
Simulated user registration encapsulates aUserDTO
When submitting data, if you use the previous method to IF ELSE
judge the use validator
of parameters, you need to add annotations.
For example non-null check:
Then you need to add no verification in the controller
method body, it will not work@Validated
@Validated
Then request the request interface and set the Email parameter to empty
parameter:
{
"userName":"luomengsun",
"mobileNo":"11111111111",
"sex":1,
"age":21,
"email":""
}
Return result:
An exception is thrown in the background
This can be verified successfully, but there is a problem that the return parameters are not ideal, and the front-end is not easy to handle the return parameters, so we add global exception handling, and then add a global unified return parameter to make it more standardized.
add global exception
Create a GlobalExceptionHandler
class, add @RestControllerAdvice
the annotation above the class and add the following code:
/** * 方法参数校验 */ @ExceptionHandler(MethodArgumentNotValidException.class) public ReturnVO handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { log.error(e.getMessage(), e); return new ReturnVO().error(e.getBindingResult().getFieldError().getDefaultMessage()); }
This method mainly captures MethodArgumentNotValidException
exceptions and then encapsulates the exception results. If you need to add other exception handling by yourself.
After adding, we are looking at the running result, calling the interface to return:
{
"code": "9999",
"desc": "邮箱不能为空",
"data": null
}
OK The exception has been handled.
Check format
If you want to verify the email format or mobile phone number, it is also very simple.
Check mailbox
/**
* 邮箱
*/
@NotBlank(message = "邮箱不能为空")
@NotNull(message = "邮箱不能为空")
@Email(message = "邮箱格式错误")
private String email;
Use regular check phone number
Verify the mobile phone number using regular verification, and then limit the number of digits
/**
* 手机号
*/
@NotNull(message = "手机号不能为空")
@NotBlank(message = "手机号不能为空")
@Pattern(regexp ="^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手机号格式有误")
@Max(value = 11,message = "手机号只能为{max}位")
@Min(value = 11,message = "手机号只能为{min}位")
private String mobileNo;
Check out the running results
Incoming parameters:
{
"userName":"luomengsun",
"mobileNo":"111111a",
"sex":1,
"age":21,
"email":"1212121"
}
Return result:
{
"code": "9999",
"desc": "邮箱格式错误",
"data": null
}
Here is an example of no longer verifying the mobile phone number
custom annotation
There are only so many annotations above. If there are special verification parameters, we can use Validator
custom annotations for verification.
First create an IdCard
annotation class
@Documented
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = IdCardValidator.class)
public @interface IdCard {
String message() default "身份证号码不合法";
Class<!--?-->[] groups() default {};
Class<!--? extends Payload-->[] payload() default {};
}
Adding @IdCard
annotations to UserDTO can be verified and triggered at runtime. This article does not explain too much about custom annotations. The next article introduces custom annotations.
- message prompt information
- groups grouping
- The payload is for the Bean
Then add IdCardValidator
the main validation logic
The method is called above is18ByteIdCardComplex
, the incoming parameter is the mobile phone number, and the ID card rules are verified by themselves Baidu: see_no_evil:
then use
@NotNull(message = "身份证号不能为空")
@IdCard(message = "身份证不合法")
private String IdCardNumber;
grouping
For example, what if the parameters in the UserDTO we defined above are to be taken?
Redefine a class and then re-annotate the parameters in it?
Validator
Provides a grouping method that perfectly solves the problem of DTO taking
Now let's modify the rules of the registered interface. Only the user name cannot be empty and other parameters are not verified.
Create a grouped interface first
public interface Create extends Default {
}
We only need to add the grouping parameter to the annotation. For example:
/**
* 用户名
*/
@NotBlank(message = "用户姓名不能为空",groups = Create.class)
@NotNull(message = "用户姓名不能为空",groups = Create.class)
private String userName;
@NotBlank(message = "邮箱不能为空",groups = Update.class)
@NotNull(message = "邮箱不能为空",groups = Update.class)
@Email(message = "邮箱格式错误",groups = Update.class)
private String email;
Then modify the Controller @Validated
to pass inCreate.class
@PostMapping("/user")
public ReturnVO userRegistra(@RequestBody @Validated(Create.class) UserDTO userDTO){
ReturnVO returnVO = userService.userRegistra(userDTO);
return returnVO ;
}
Then the call passes in the parameters:
{
"userName":"",
}
Return parameter:
{
"code": "9999",
"desc": "用户姓名不能为空",
"data": null
}
OK Now only the Create is verified, and the Updata group is not verified. If you need to reuse DTO, you can use group verification
Check a single parameter
When developing, you must have encountered a single parameter, and you can add a comment in front of the parameter.
@PostMapping("/get")
public ReturnVO getUserInfo(@RequestParam("userId") @NotNull(message = "用户ID不能为空") String userId){
return new ReturnVO().success();
}
Then add @Validated
annotations to the Controller class, pay attention not to add it in front of the parameters.