十三、企业开发(5)

本章概要

  • 数据校验

13.5 数据校验

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

13.5.1 普通校验

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

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

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

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

创建 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;
    }
}

代码解释:

  • @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;
    }
}

代码解释:

  • 给 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;
    }
}

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

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

13.5.2 分组校验

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

public interface ValidationGroup1 {
}
public interface ValidationGroup2 {
}

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

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;
    }
}

这次在部分注解中添加了 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;
    }
}

@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 值必须为正整数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只小熊猫呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值