springboot之Validation参数校验详细解读
作者:知识追寻者
这篇文章主要介绍了springboot之Validation参数校验详细解读,本篇是关于springboot的参数校验知识,当然也适用其它java应用,读完本篇将学会基本的参数校验,自定义参数校验和分组参数校验,需要的朋友可以参考下
一 Validation参数校验
Validation参数校验是指在程序运行中对传进来的参数进行合法性检查,以保证程序的正确性和安全性。在实际开发中,正确的校验能够避免因恶意输入或错误输入而导致的程序崩溃、漏洞等问题。
二 校验入门
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.3 实体约束示例
简单注解约束使用示例如下;如果成员是实体,需要带上 @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.4 控制层示例
- 需要在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.5 异常捕获
全局异常捕获,当出现参数校验不合法时捕获异常,并且返回给前端;
/** * @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.6 请求示例
三 自定义校验规则
特殊的字段需要自定义规则,比如身份证号码,邮箱,电话等;
定义校验注解
@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); }
到此这篇关于springboot之Validation参数校验详细解读的文章就介绍到这了,更多相关Validation参数校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!