zoukankan      html  css  js  c++  java
  • 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 控制层示例

    1. 需要在class加上 @Validated
    2. 如果参数是实体 需要 加上 @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

  • 相关阅读:
    定义类或对象
    CSS 超出的文字显示省略号(单行、多行)
    获取Json对象的长度以及判断json对象是否为空
    第三次作业附加
    八皇后问题解题报告(dfs
    STL学习笔记(不定期更新)
    寒假作业之三
    寒假作业之二(2)
    寒假作业之二(1)
    第一篇随笔居然是总结耶
  • 原文地址:https://www.cnblogs.com/zszxz/p/13089387.html
Copyright © 2011-2022 走看看