• 十三、企业开发(5)


    本章概要

    • 数据校验

    13.5 数据校验

    数据校验时开发过程中一个常见的环节,一般来说,为了提高系统运行效率,都会在前端进行数据校验,但是这并不意味着不必在后端做数据校验了,因为用户还是可能在获取数据接口后手动传入非法数据。

    13.5.1 普通校验

    普通校验时基础用法,首先在 Spring Boot Web 项目中添加 数据校验相关的依赖

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-validationartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    项目创建成功后,查看 LocalValidatorFactoryBean 类的源码,发现默认的 ValidationMessageSource (校验出错时的提示文件)是 resources 目录下的 ValidationMessage.properties 文件,创建该文件。

    user.name.size=用户名长度介于5到10个字符之间
    user.address.notnull=用户地址不能为空
    user.age.size=年龄输入不正确
    user.email.notnull=邮箱不能为空
    user.email.pattern=邮箱格式不正确
    
    • 1
    • 2
    • 3
    • 4
    • 5

    创建 User 类,配置数据校验

    public class User {
        private Integer id;
        @Size(min = 5,max = 10,message = "{user.name.size}")
        private String name;
        @NotNull(message = "{user.address.notnull}")
        private String address;
        @DecimalMin(value = "1",message = "{user.age.size}")
        @DecimalMax(value = "200",message = "{user.age.size}")
        private Integer age;
        @Email(message = "{user.email.pattern}")
        @NotNull(message = "{user.email.notnull}")
        private String email;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    }
    
    • 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
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    代码解释:

    • @Size 表示一个字符串的长度或者一个集合的大小,必须在某一个范围中;min 参数表示范围的下限;max 参数表示范围的上线;message 表示校验失败时的提示信息
    • @NotNull 注解表示该字段不能为空
    • @DecimalMin 注解表示对应属性值的下限,@DecimalMax 注解表示对应属性值的上限
    • @Email 注解表示对应属性格式是一个 Email

    接着创建 Controller

    @RestController
    public class UserController {
        @PostMapping("/user")
        public List<String> addUser(@Validated User user, BindingResult result){
            List<String> errors = new ArrayList<>();
            if (result.hasErrors()){
                List<ObjectError> allErrors = result.getAllErrors();
                for (ObjectError error : allErrors){
                    errors.add(error.getDefaultMessage());
                }
            }
            return errors;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    代码解释:

    • 给 User 参数添加 @Validated 注解,表示需要对该参数做校验,紧接着的 BindingResult 参数表示在校验出错时保存的出错信息
    • 如果 BindingResult 中的 hasErrors 方法返回 true ,表示有错误信息,此时遍历错误信息,将其返回给前端

    启动项目,使用 Postman 直接访问 “http://localhost:8080/user”接口
    在这里插入图片描述

    出现乱码情况,添加配置类,覆盖其中的 getValidator 方法

    @Configuration
    public class WebMvcConfig extends WebMvcConfigurationSupport {
        @Override
        protected Validator getValidator() {
            ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
            // 读取配置文件的编码格式
            messageSource.setDefaultEncoding("utf-8");
            // 缓存时间,-1表示不过期
            messageSource.setCacheMillis(-1);
            // 配置文件前缀名,设置为Messages,那你的配置文件必须以Messages.properties/Message_en.properties...
            messageSource.setBasename("ValidationMessages");
            LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
            MessageInterpolatorFactory interpolatorFactory = new MessageInterpolatorFactory();
            factoryBean.setMessageInterpolator(interpolatorFactory.getObject());
            factoryBean.setValidationMessageSource(messageSource);
            return factoryBean;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    重启项目,再次访问
    在这里插入图片描述

    如果传入用户地址、一个非法邮箱地址、一个格式不正确的用户名,结果如下
    在这里插入图片描述

    13.5.2 分组校验

    有的时候开发者在某一个实体类中定义了很多校验规则,但是在某一次业务处理中,并不需要这么多校验规则,此时就可以使用分组校验。
    首先创建两个分组接口

    public interface ValidationGroup1 {
    }
    
    • 1
    • 2
    public interface ValidationGroup2 {
    }
    
    • 1
    • 2

    然后在实体类中添加分组信息

    public class User {
        private Integer id;
        @Size(min = 5,max = 10,message = "{user.name.size}",groups = ValidationGroup1.class)
        private String name;
        @NotNull(message = "{user.address.notnull}",groups = ValidationGroup2.class)
        private String address;
        @DecimalMin(value = "1",message = "{user.age.size}")
        @DecimalMax(value = "200",message = "{user.age.size}")
        private Integer age;
        @Email(message = "{user.email.pattern}")
        @NotNull(message = "{user.email.notnull}",groups = {ValidationGroup1.class,ValidationGroup2.class})
        private String email;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    }
    
    • 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
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    这次在部分注解中添加了 groups 属性,表示该校验规则所属的分组,接下来在 @Validated 注解中指定校验分组

    @RestController
    public class UserController {
        @PostMapping("/user")
        public List<String> addUser(@Validated(ValidationGroup2.class) User user, BindingResult result){
            List<String> errors = new ArrayList<>();
            if (result.hasErrors()){
                List<ObjectError> allErrors = result.getAllErrors();
                for (ObjectError error : allErrors){
                    errors.add(error.getDefaultMessage());
                }
            }
            return errors;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    @Validated(ValidationGroup2.class 表示这里的校验使用 ValidationGroup2 分组的校验规则,即只校验邮箱地址是否为空、用户地址是否为空。
    输入错误的邮箱地址、错误的用户名,测试结果如下
    在这里插入图片描述

    13.5.3 校验注解

    实际上的校验注解布置前面提到的几个,完整的校验注解如下

    • @NotNull 值不能为空
    • @Null 值必须为空
    • @Pattern(regex=) 字符串必须匹配正则表达式
    • @Size 集合或者数组元素的数量必须在min和max之间
    • @CreditCardNumber(ignoreNonDigitCharacters=) 字符串必须是信用卡号,按照美国的标准验证
    • @Email 字符串必须是Email格式
    • @Length(min,max) 校验字符串的长度
    • @NotBlank 字符串不能为空串
    • @NotEmpty 字符串不能为null,集合或者数组的size不能为空
    • @Range(min,max) 数字必须大于min,小于max
    • @SafeHtml 字符串必须是安全的html
    • @URL 字符串必须是合法的URL地址
    • @AssertFalse 值必须是false
    • @AssertTrue 值必须是true
    • @DecimalMax(value=,inclusive=) ( inclusive=true 小于等于 / inclusive =false 小于)值必须小于等于/小于指定的值,也可以注解在字符串类型的属性上
    • @DecimalMin(value=,inclusive=) ( inclusive=true 大于等于 / inclusive =false 大于)值必须大于等于/大于指定的值,也可以注解在字符串类型的属性上
    • @Digist(integer=) 数字格式检查。integer指定整数部分的最大长度,fraction指定小数部分的最大长度
    • @Future 时间必须是未来的
    • @Past 事件必须是过去的
    • @Max(vaue=) 值必须小于等于value指定的值,不能注解在字符串类型的属性上
    • @Min(value=) 值必须大于等于value指定的值,不能注解在字符串类型的属性上
    • @PositiveOrZero 值必须为正整数
  • 相关阅读:
    神经网络之万能定理python-pytorch实现,可以拟合任意曲线
    Gavin Wood 演讲全文:建设更具韧性以应变化的 Polkadot
    在两台CentOS 7服务器上部署MinIO集群。
    iOS QR界面亮度调整
    使用HBuilderX将H5网页打包成APP
    Angular 使用教程——基本语法和双向数据绑定
    JSP学习笔记【三】——JQuery
    Bootstrap主页面搭建(十四)
    javascript的动态作用域和静态作用域
    springboot网络安全平台设计毕业设计源码042335
  • 原文地址:https://blog.csdn.net/GXL_1012/article/details/126385580