项目中经常需要对请求参数进行校验。不仅麻烦,冗长的 if 判断语句使代码显得十分臃肿。本文介绍使用 @Valid 注解方式配置校验,直接定义在字段处,方便又简洁。 javax.validation.Valid 底层是通过AOP技术,对请求拦截,若请求参数不满足要求,则直接抛出异常,统一处理后响应给前端。
用法
引入依赖
@Valid相关注解主要涉及到hibernate-validator 和 validation-api两个依赖。springboot项目只要引入 spring-boot-starter-web 依赖即可,hibernate-validator 和 validation-api依赖已经包含在内
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
|
具体依赖关系如下:

标示要校验的参数
例如要对userVO对象做参数校验,则在userVO前加上 javax.validation.Valid注解,表示开启对该参数校验
1 2 3 4 5 6 7 8 9 10
| import javax.validation.Valid;
@RestController public class ValidController {
@PostMapping(value = "/ice/check", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public CommonResponse checkUser(@RequestBody @Valid UserVO userVO){ return new CommonResponse("200", "OK"); } }
|
配置字段校验
@Valid只是表示开启校验,还需要在具体字段上加上校验内容。
相关注解都在org.hibernate.validator.constraints 和 javax.validation.constraints包下。如@NotBlank表示对应字段不能为空。其中参数message表示异常信息,不填则使用默认异常信息。
如果需要对成员变量内部的字段进行校验(如education内的字段),则除了要在Education内配置注解,还要在education上加上@Valid,形成递归校验
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import lombok.Data;
import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size;
@Data public class UserVO {
@NotBlank(message = "姓名不能为空") private String name;
@NotNull(message = "年龄不能为空") @Max(value = 35, message = "年龄不超过45") @Min(value = 23, message = "年龄不低于18") private Integer age;
@NotBlank(message = "密码不能为空") @Size(min = 8, max = 12, message = "密码长度要在8-12之间") private String password;
@Email @NotBlank(message = "邮箱不能为空") private String email; @Valid private Education education; }
|
常用注解说明
| 注解 |
作用 |
属于包 |
| Email |
校验邮箱格式 |
org.hibernate.validator.constraints |
| NotBlank |
字符串不能为空或不填 |
org.hibernate.validator.constraints |
| Max |
整型最大不超过 |
javax.validation.constraints |
| Min |
整型最小不超过 |
javax.validation.constraints |
| NotNull |
整型不能为null |
javax.validation.constraints |
| Size |
字符串长度 |
javax.validation.constraints |
全局异常处理
都配置好后,解析到不满足要求的字段,会抛出 MethodArgumentNotValidException 异常。还需要统一处理,响应给前端。
创建 CommonExceptionHandler类,用@RestControllerAdvice注解标注,表示这是一个处理全局控制器的配置类。


在方法上用 @ExceptionHandler 注解标注,并指定要处理的异常。应用启动后,这些方法会被作用在@REquestMapping 注解的方法上(即接口方法)。
配置代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice public class CommonExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<CommonResponse> methodArgumentNotValidHandler(MethodArgumentNotValidException e) { String message = e.getBindingResult().getAllErrors().stream() .map(DefaultMessageSourceResolvable::getDefaultMessage) .collect(Collectors.joining(",")); CommonResponse resp = new CommonResponse(); resp.setResultCode("-1"); resp.setReturnMessage(message); resp.setData(new HashMap<>()); return new ResponseEntity<>(resp, HttpStatus.OK); } }
|
验证
