Introduction
In daily interface development, in order to prevent illegal parameters from affecting the business, it is often necessary to verify the parameters of the interface. For example, when logging in, it is necessary to verify whether the user name and password are empty. When adding a user, verify whether the format of the user's email address and mobile phone number is correct. It would be too cumbersome to rely on code to verify interface parameters one by one, and the readability of the code would be extremely poor.
Validator
The framework is designed to solve the problem of developers writing less code during development and improving development efficiency; Validator is specially used to verify interface parameters, such as common required verification, email Format verification, the username must be between 6 and 12, etc.
Next let’s take a look at how to integrate the parameter verification framework in SpringbBoot.
1.Integrated parameter verification in SpringBoot
1.1Introducing dependencies
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
1.2Define parameter entity classes
package com.didiplus.modules.sys.domain; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/25 * Desc: 字典类型领域模型 */ @Data @ApiModel(value = "字典类型") public class SysDictType { @ApiModelProperty("ID") private String id; @NotBlank(message = "字典名称必填项") @ApiModelProperty(value = "字典名称",example = "用户ID") private String typeName; @NotBlank(message = "字典编码不能为空") @ApiModelProperty(value = "字典编码") private String typeCode; @Email(message = "请填写正确的邮箱地址") @ApiModelProperty(value = "字典编码") private String email; @ApiModelProperty(value = "字典描述") private String description; @NotBlank(message = "字典状态不能为空") @ApiModelProperty(value = "字典状态") private String enable; }
Common constraint annotations are as follows:
Annotation | Function |
---|---|
@AssertFalse | can be null, if not null Must be false |
@AssertTrue | can be null, if not null it must be true |
@DecimalMax | The setting cannot exceed the maximum value |
@DecimalMin | The setting cannot exceed the minimum value |
@Digits | The setting must be a number and the number of integer digits and decimal digits must be within the specified range |
@Future | The date must be within the current date The future |
@Past | date must be in the past |
@Max | max of the current date This maximum value must not be exceeded |
@Min | The maximum must not be less than this minimum value |
@NotNull | Cannot be null, can be empty |
@Null | Must be null |
@Pattern | Must satisfy the specified regular expression |
@Size | The size() value of collections, arrays, maps, etc. must be within the specified range |
Must be in email format | |
@Length | The length must be within the specified range |
@NotBlank | The string cannot be null, and the string after trim() cannot be equal to "" |
@NotEmpty | Cannot be null, size() of collections, arrays, maps, etc. cannot be 0; string trim() can be equal to "" |
@Range | The value must be Within the specified range |
@URL | must be a URL |
1.3定义校验类进行测试
package com.didiplus.modules.sys.controller; import com.didiplus.modules.sys.domain.SysDictType; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.parameters.RequestBody; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/25 * Desc: 数据字典控制器 */ @RestController @Api(tags = "数据字典") @RequestMapping("/api/sys/dictType") public class SysDictTypeController { @ApiOperation("字典添加") @PostMapping("/add") public SysDictType add(@Validated @RequestBody SysDictType sysDictType) { return sysDictType; } @ApiOperation("字典修改") @PutMapping("/edit") public SysDictType edit(@Validated @RequestBody SysDictType sysDictType) { return sysDictType; } }
这里我们先定义两个方法add
,edit
,都是使用了 @RequestBody
注解,用于接受前端发送的json
数据。
1.4打开接口文档模拟提交数据
通过接口文档看到前三个字段都是必填项。
由于email的格式不对就被拦截了,提示是因为邮箱地址不对。
2.参数异常加入全局异常处理器
虽然我们之前定义了全局异常拦截器,也看到了拦截器确实生效了,但是Validator
校验框架返回的错误提示太臃肿了,不便于阅读,为了方便前端提示,我们需要将其简化一下。
直接修改之前定义的 RestExceptionHandler
,单独拦截参数校验的三个异常:
javax.validation.ConstraintViolationException
org.springframework.validation.BindException
org.springframework.web.bind.MethodArgumentNotValidException
代码如下:
package com.didiplus.common.web.response.Handler; import com.didiplus.common.web.response.Result; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindException; import org.springframework.validation.ObjectError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.validation.ValidationException; import java.util.stream.Collectors; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/24 * Desc: 默认全局异常处理。 */ @RestControllerAdvice public class RestExceptionHandler { /** * 默认全局异常处理。 * @param e the e * @return ResultData */ @ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class}) public ResponseEntity<Result<String>> handleValidatedException(Exception e) { Result<String> result = null; if (e instanceof MethodArgumentNotValidException) { MethodArgumentNotValidException ex =(MethodArgumentNotValidException) e; result = Result.failure(HttpStatus.BAD_REQUEST.value(), ex.getBindingResult().getAllErrors().stream() .map(ObjectError::getDefaultMessage) .collect(Collectors.joining(";")) ); } else if (e instanceof ConstraintViolationException){ ConstraintViolationException ex = (ConstraintViolationException) e; result = Result.failure(HttpStatus.BAD_REQUEST.value(), ex.getConstraintViolations().stream() .map(ConstraintViolation::getMessage) .collect(Collectors.joining(";")) ); }else if (e instanceof BindException) { BindException ex = (BindException ) e; result = Result.failure(HttpStatus.BAD_REQUEST.value(), ex.getAllErrors().stream() .map(ObjectError::getDefaultMessage) .collect(Collectors.joining(";")) ); } return new ResponseEntity<>(result,HttpStatus.BAD_REQUEST); } }
美化之后错误信息提示更加友好
3.自定义参数校验
虽然Spring Validation 提供的注解基本上够用,但是面对复杂的定义,我们还是需要自己定义相关注解来实现自动校验。
比如上面实体类中添加的sex性别属性,只允许前端传递传 M,F 这2个枚举值,如何实现呢?
3.1创建自定义注解
package com.didiplus.common.annotation; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.Documented; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/26 * Desc: */ @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE}) @Retention(RUNTIME) @Repeatable(EnumString.List.class) @Documented @Constraint(validatedBy = EnumStringValidator.class)//标明由哪个类执行校验逻辑 public @interface EnumString { String message() default "value not in enum values."; Class<?>[] groups() default {}; Class<? extends Payload>[] palyload() default {}; /** * @return date must in this value array */ String[] value(); /** * Defines several {@link EnumString} annotations on the same element. * * @see EnumString */ @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE}) @Retention(RUNTIME) @Documented @interface List { EnumString[] value(); } }
3.2自定义校验逻辑
package com.didiplus.common.annotation; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.Arrays; import java.util.List; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/26 * Desc: */ public class EnumStringValidator implements ConstraintValidator<EnumString,String> { private List<String> enumStringList; @Override public void initialize(EnumString constraintAnnotation) { enumStringList = Arrays.asList(constraintAnnotation.value()); } @Override public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { if(value == null) { return true; } return enumStringList.contains(value); } }
3.3在字段上增加注解
@ApiModelProperty(value = "性别") @EnumString(value = {"F","M"}, message="性别只允许为F或M") private String sex;
3.4体验效果
4.分组校验
一个对象在新增的时候某些字段是必填,在更新是有非必填。如上面的 SysDictType
中id
属性在新增操作时都是必填。 面对这种场景你会怎么处理呢?
其实 Validator
校验框架已经考虑到了这种场景并且提供了解决方案,就是分组校验。 要使用分组校验,只需要三个步骤:
4.1定义分组接口
package com.didiplus.common.base; import javax.validation.groups.Default; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/26 * Desc: */ public interface ValidGroup extends Default { interface Crud extends ValidGroup{ interface Create extends Crud{ } interface Update extends Crud{ } interface Query extends Crud{ } interface Delete extends Crud{ } } }
4.2在模型中给参数分配分组
@Null(groups = ValidGroup.Crud.Create.class) @NotNull(groups = ValidGroup.Crud.Update.class,message = "字典ID不能为空") @ApiModelProperty("ID") private String id;
4.3体现效果
The above is the detailed content of How does SpringBoot perform parameter verification?. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Atom editor mac version download
The most popular open source editor

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

Dreamweaver CS6
Visual web development tools