springboot之Validation参数校验
一 前言
本篇是关于springboot的参数校验知识,当然也适用其它java应用;读完本篇将学会基本的参数校验,自定义参数校验和分组参数校验;良好的代码规范和书写方式犹如散文版清丽脱俗,行云流水;
公众号:知识追寻者
知识追寻者(Inheriting the spirit of open source, Spreading technology knowledge;)
二 校验入门
2.1 pom.xml
springboot在 web启动器中已经包含validator包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
非springboot项目,需要自行引入依赖
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.5.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.el</artifactId>
<version>3.0.3</version>
</dependency>
2.2 常用约束说明
@Null
: 元素为 null@NotNull
: 元素不为 null@AssertTrue
: 元素为 true@AssertFalse
: 元素为 false@Min(value)
: 数字的值大于等于指定的最小值@Max(value)
: 个数字的值小于等于指定的最大值@DecimalMin(value)
:大数值大于等于指定的最小值@DecimalMax(value)
: 大数值小于等于指定的最大值@Size(max=, min=)
: 元素的大小在指定的范围内@Digits (integer, fraction)
: 元素是一个数字,其值必须在可接受的范围内@Past
: 一个过去的日期@Future
: 一个将来的日期@Pattern(regex=,flag=)
:指定的正则表达式@URL
:必须是一个URL@Email
:必须是email格式@NotBlank
: 字符串不能为空@NotEmpty
:集合不能为空@Length
: 长度必须在指定范围内@Valid
:对实体类进行校验
2.4 实体约束示例
- 简单注解约束使用示例如下;
- 如果成员是实体,需要带上
@Valid
注解;
/**
* @Author lsc
* <p> </p>
*/
@Data
public class SysUser {
private Long id;
@NotNull(message ="用户名不能为空")
@Size(min = 3, max = 5, message = "用户名长度为{min}-{max}之间")
private String username;
@NotNull(message ="昵称不能为空")
private String name;
@NotNull(message ="密码不能为空")
private String password;
@Email(message = "邮箱格式不合法")
private String email;
private String gender;
}
2.5 控制层示例
- 需要在class加上
@Validated
; - 如果参数是实体 需要 加上
@Valid
注解
/**
* @Author lsc
* <p> </p>
*/
@RestController
@Validated
public class SysUserController {
// 方法参数为实体校验
@PostMapping("/register")
public ResponseEntity register(@Valid @RequestBody SysUser sysUser){
return ResponseEntity.ok(sysUser);
}
// 方法参数校验
@GetMapping("user")
public ResponseEntity getUser(@NotNull(message ="用户名不能为空") String username) {
SysUser sysUser = new SysUser();
sysUser.setName("知识追寻者");
return ResponseEntity.ok(sysUser);
}
}
2.6 异常捕获
全局异常捕获,当出现参数校验不合法时捕获异常,并且返回给前端;
/**
* @Author lsc
* <p> </p>
*/
@ControllerAdvice
public class GlobHandler {
// 捕获方法参数校验异常
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public ResponseEntity constraintViolationExceptionHandler(ConstraintViolationException e){
Set<ConstraintViolation<?>> message = e.getConstraintViolations();
HashMap<String, Object> map = new HashMap<>();
message.stream().forEach(msg -> {
String path = msg.getPropertyPath().toString();
String field = path.substring(path.indexOf(".")+1);
map.put(field,msg.getMessageTemplate());
});
return ResponseEntity.ok(map);
}
// 捕获实体参数校验异常
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResponseEntity resolveMethodArgumentNotValidException(MethodArgumentNotValidException e){
List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
HashMap<String, Object> map = new HashMap<>();
allErrors.stream().forEach(error -> {
FieldError fieldError = (FieldError) error;
map.put(fieldError.getField(), fieldError.getDefaultMessage());
});
return ResponseEntity.ok(map);
}
}
2.7 请求示例
三 自定义校验规则
特殊的字段需要自定义规则,比如身份证号码,邮箱,电话等;
定义校验注解
@Target({ METHOD, FIELD })
@Retention(RUNTIME)
@Constraint(validatedBy = GenderValidator.class)
@Documented
public @interface Gender {
String message() default "性别为男或者女";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default {};
}
GenderValidator 实现 ConstraintValidator 接口并提供校验规则
/**
* @Author lsc
* <p> </p>
*/
public class GenderValidator implements ConstraintValidator<Gender, String> {
// 初始化校验值
@Override
public void initialize(Gender constraintAnnotation) {
}
// 校验规则
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return "男".equals(value) || "女".equals(value);
}
}
在成员变量使用 注解
@Gender()
private String gender;
四 分组校验
默认情况下,不指定分组都属于默认组;使用分组校验有利于分层校验开发;
新建2个接口,一个用于查询, 一个用于添加
/**
* @Author lsc
* <p> </p>
*/
public interface ADD extends Default {
}
public interface Select extends Default {
}
修改 实体校验规则,如果不指定分组 默认是 Default 组;
@NotNull(message ="用户名不能为空",groups = ADD.class)
@Size(min = 3, max = 5, message = "用户名长度为{min}-{max}之间")
private String username;
@NotNull(message ="昵称不能为空", groups = Select.class)
private String name;
@NotNull(message ="密码不能为空",groups = ADD.class)
private String password;
@Email(message = "邮箱格式不合法", groups = Select.class)
private String email;
控制层示例,此时只会校验 ADD 组和 Default组
// 分组校验
@PostMapping("/user")
public ResponseEntity addUser(@Validated(value = ADD.class) @RequestBody SysUser sysUser){
return ResponseEntity.ok(sysUser);
}
五 参考文档
https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/
https://zhuanlan.zhihu.com/p/96403211
https://blog.csdn.net/justry_deng/article/details/86571671
https://juejin.im/post/5dc8bc745188254e7a155ba0
https://www.jianshu.com/p/89a675b7c900
本套教程
- springboot入门 (1)
- Springboot自定义banner(2)
- springboot配置文件解析(3)
- springboot集成mybatis(4)
- springboot集成jdbcTemplate(5)
- spingboot单元测试(6)
- springboot集成thymeleaf(7)
- springboot多文件上传(8)
- springboot文件下载(9)
- Springboot自定义异常类(10)
- springboot多环境配置(11)
- springboot自动配置原理解析(12)
- springboot集成restTemplate接口调用(13)
- springboot集成任务调度(14)
- springboot跨域CORS处理(15)
- springboot开启GIZP压缩(16)
- springboot集成logback(17)
- springboot集成Swagger(18)
- springboot集成actuator后台监控(19)
- springboot集成mybatis+oracle+druid(20)
- springboot 集成springsession(21)
- springboot集成jwt(22)
- springboot集成admin后台监控(23)
- springboot集成redis基础篇(24)
- springboot集成redis缓存篇(25)
- springboot使用AOP日志拦截(26)
- springboot集成Validation参数校验(27)
- springboot集成mybatisPlus(28)
- springboot集成shiro(29)
- springboot实现接口等幂次校验(30)
- springboot-集成WebSockets(31)
- restTemplate源码解析(32)
- SpringBoot使用@Async异步调用与线程池(33)
- 待续