SpringBoot数据校验

本文详细介绍了如何在SpringBoot项目中利用内置的validation模块进行数据校验,包括普通校验的配置、@Size、@NotEmpty、日期和数值检查,以及分组校验的使用场景和步骤,确保后端接口的安全性。
摘要由CSDN通过智能技术生成

SpringBoot数据校验

数据校验是开发过程中一个常见的环节,一般来说,为了提高系统运行效率,都会在前端进行数据校验,但是这并不意味着不必在后端做数据校验了,因为用户还是可能在获取数据接口后手动传入非法数据,所以后端还是需要做数据校验。SpringBoot对此也提供了相关的自动化配置解 决方案,下 面分别予以介绍。

1. 普通校验

1.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</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

1.2 创建校验出错的提示文件

resources 目录下创建一个 ValidationMessages.properties 文件(默认的创建校验出错的提示文件),里面内容如下:

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

1.3 数据校验配置

接下来创建一个 User 类,并配置相关的数据校验:

@NoArgsConstructor
@Data
public class User  {
    // @Size 注解表示一个字符串的长度或者一个集合的大小,必须在某一个范围中
    @Size(min = 5, max = 10, message = "{user.name.size}")
    private String name;

    // @NotEmpty 注解表示该字段不能为空
    @NotEmpty(message = "{user.address.notnull}")
    private String address;

    // @DecimalMin 注解表示对应属性值的下限
    @DecimalMin(value = "1", message = "{user.age.size}")
    // @DecimalMax 注解表示对应属性值的上限
    @DecimalMax(value = "200", message = "{user.age.size}")
    private Integer age;

    // @Email 注解表示对应属性格式是一个 Email
    @Email(message = "{user.email.pattern}")
    // @NotNull 注解表示该字段不能为null
    @NotNull(message = "{user.email.notnull}")
    private String email;
}

1.4 Controller 配置

接下来创建一个 Controller,给 User 参数添加 @Validated 注解,表示需要对该参数做校验,后面的 BindingResult 参数表示在校验出错时保存的出错信息。

@RestController
public class HelloController {

    @PostMapping("/user")
    public List<String> addUser(@Validated User user, BindingResult result) {
        List<String> errors = new ArrayList<>();
        // 如果 BindingResult 的 hasErrors 方法返回true,则表示有错误信息
        if (result.hasErrors()) {
            List<ObjectError> allErrors = result.getAllErrors();
            /// 遍历错误信息,返回给前端
            for (ObjectError error : allErrors) {
                errors.add(error.getDefaultMessage());
            }
        }
        return errors;
    }
}

1.5 运行测试

(1)启动项目后,我们如果直接访问“/user”接口,则返回如下信息:

在这里插入图片描述

(2)如果传入用户地址、一个非法邮件地址以及一个格式不正确的用户名,结果如下:

在这里插入图片描述

2. 分组校验

有的时候,我们在某一个实体类中定义了很多校验规则,但是在某一次业务处理中,并不需要这么多校验规则,此时就可以使用分组校验。具体步骤如下。

2.1 创建分组接口

首先创建两个分组接口:

public interface ValidationGroup1 {
}
 
public interface ValidationGroup2 {
}

2.2 在实体类中添加分组信息

这次在注解中添加了 groups 属性,表示该校验规则所属的分组:

@NoArgsConstructor
@Data
public class User  {
    // @Size 注解表示一个字符串的长度或者一个集合的大小,必须在某一个范围中
    @Size(min = 5, max = 10, message = "{user.name.size}", groups = ValidationGroup1.class)
    private String name;

    // @NotEmpty 注解表示该字段不能为空
    @NotEmpty(message = "{user.address.notnull}", groups = ValidationGroup2.class)
    private String address;

    // @DecimalMin 注解表示对应属性值的下限
    @DecimalMin(value = "1", message = "{user.age.size}")
    // @DecimalMax 注解表示对应属性值的上限
    @DecimalMax(value = "200", message = "{user.age.size}")
    private Integer age;

    // @Email 注解表示对应属性格式是一个 Email
    @Email(message = "{user.email.pattern}")
    // @NotNull 注解表示该字段不能为null
    @NotNull(message = "{user.email.notnull}", groups = ValidationGroup2.class)
    private String email;
}

2.3 在 Controller 中指定校验分组

接下来在 @Validated 注解中指定校验分组,这里的 @Validated(ValidationGroup2.class) 表示这里的校验使用 ValidationGroup2 分组的校验规则(只校验用户地址、邮箱地址是否为空

@RestController
public class HelloController {

    @PostMapping("/user")
    public List<String> addUser(@Validated(ValidationGroup2.class) User user,
                                BindingResult result) {
        List<String> errors = new ArrayList<>();
        // 如果 BindingResult 的 hasErrors 方法返回true,则表示有错误信息
        if (result.hasErrors()) {
            List<ObjectError> allErrors = result.getAllErrors();
            /// 遍历错误信息,返回给前端
            for (ObjectError error : allErrors) {
                errors.add(error.getDefaultMessage());
            }
        }
        return errors;
    }
}

2.4 运行测试

启动项目,再次发起请求进行测试,可以看到这次只校验邮箱地址是否为空,用户地址是否为空.

附:校验注解汇总

上面的样例只是演示了几个常见的校验注解,实际上校验注解远不止这几个,下面是完整的校验注解参考表。

验证注解验证的数据类型说明
空检查
@Null任意类型验证注解的元素值是 null
@NotNull任意类型验证注解的元素不是 null
@NotBlankCharSequence 子类型(CharBufferStringStringBufferStringBuilder验证注解的元素值不为空(不为 null、去除首尾空格后长度不为 0),不同于 @NotEmpty@NotBlank 只应用于字符串且在比较时会去除字符串的首尾空格
@NotEmptyCharSequence 子类型、CollectionMap、数组验证注解的元素值不为 null 且不为空(字符串长度不为 0、集合大小不为 0
Boolean检查
@AssertFalseBooleanboolean验证注解的元素值是 false
@AssertTrueBooleanboolean验证注解的元素值是 true
长度检查
@Size(min=下限, max=上限)字符串、CollectionMap、数组等验证注解的元素值的在 minmax(包含)指定区间之内,如字符长度、集合大小
@Length(min=下限, max=上限)CharSequence 子类型验证注解的元素值长度在 minmax 区间内
日期检查
@Pastjava.util.Datejava.util.CalendarJoda-Time 类库的日期类型验证注解的元素值(日期类型)比当前时间早
@Future@Past 要求一样验证注解的元素值(日期类型)比当前时间晚
@PastOrPresent@Past 要求一样验证注解的元素值(日期类型)比当前时间早,或者是当前时间
@FutureOrPresent@Past 要求一样验证注解的元素值(日期类型)比当前时间晚,或者是当前时间
数值检查
@MIN(value=值)BigDecimalBigInteger, byteshort, int, long,等任何 NumberCharSequence(存储的是数字)子类型验证注解的元素值大于等于 @Min 指定的 value
@MAX(value=值)@Min 要求一样验证注解的元素值小于等于 @Max 指定的 value
@DecimalMin(value=值)@Min 要求一样验证注解的元素值大于等于 @ DecimalMin 指定的 value
@DecimalMax(value=值)@Min 要求一样验证注解的元素值小于等于 @ DecimalMax 指定的 value
@Digits(integer=整数位数, fraction=小数位数)@Min 要求一样验证注解的元素值的整数位数和小数位数上限
@Range(min=最小值, max=最大值)BigDecimalBigIntegerCharSequencebyteshortintlong等原子类型和包装类型验证注解的元素值在最小值和最大值之间
@Negative@Range 要求一样验证注解的元素必须是负数
@NegativeOrZero@Range 要求一样验证注解的元素必须是负数或 0
@Positive@Range 要求一样验证注解的元素必须是正数
@PositiveOrZero@Range 要求一样验证注解的元素必须是正数或 0
其他检查
@Valid任何非原子类型指定递归验证关联的对象;如用户对象中有个地址对象属性,如果想在验证用户对象时一起验证地址对象的话,在地址对象上加 @Valid 注解即可级联验证
@Pattern(regexp=正则表达式,flag=标志的模式)CharSequence 的子类型验证注解的元素值与指定的正则表达式匹配
@Email(regexp=正则表达式,flag=标志的模式)CharSequence 的子类型验证注解的元素值是 Email,也可以通过 regexpflag 指定自定义的 email 格式
@CreditCardNumberCharSequence 的子类型验证注解元素值是信用卡卡号
@ScriptAssert(lang= ,script=)业务类校验复杂的业务逻辑
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值