Validation in Spring Boot

在springboot中常用的用于参数校验的注解如下:

@AssertFalse 所注解的元素必须是Boolean类型,且值为false
@AssertTrue 所注解的元素必须是Boolean类型,且值为true
@DecimalMax 所注解的元素必须是数字,且值小于等于给定的值
@DecimalMin 所注解的元素必须是数字,且值大于等于给定的值
@Digits 所注解的元素必须是数字,且值必须是指定的位数
@Future 所注解的元素必须是将来某个日期
@Max 所注解的元素必须是数字,且值小于等于给定的值
@Min 所注解的元素必须是数字,且值小于等于给定的值
@Range 所注解的元素需在指定范围区间内
@NotNull 所注解的元素值不能为null
@NotBlank 所注解的元素值有内容
@Null 所注解的元素值为null
@Past 所注解的元素必须是某个过去的日期
@PastOrPresent 所注解的元素必须是过去某个或现在日期
@Pattern 所注解的元素必须满足给定的正则表达式
@Size 所注解的元素必须是String、集合或数组,且长度大小需保证在给定范围之内
@Email 所注解的元素需满足Email格式

一、添加依赖

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

二 、实体类参数校验

2.1 实体类中添加注解

@Table(name = "sys_table_setting")
@Data
@NoArgsConstructor
public class SysTableSettingDTO {
    /**
     * 主键id
     */
    @NotNull(message = "setting汇总ID不能为null")
    @Id
    private Integer id;
@Table(name = "sys_table_setting_details")
@Data
@NoArgsConstructor
public class SysTableSettingDetailsDTO {
    /**
     * 主键id
     */
    @NotNull(message = "setting明细ID不能为null")
    @Id
    private Integer id;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SettingAndDetails {
    @NotNull(message = "setting汇总不能为null")
    @Valid
    private SysTableSettingDTO sysTableSettingDTO;
    @NotEmpty(message = "setting明细List不能为空集合")
    private List<@Valid SysTableSettingDetailsDTO> sysTableSettingDetailsDTOList;
    private List<@Valid SysTableSettingDetailsDTO> detailsDTOListDeleted;
}

2.2 Controller添加注解

@PostMapping("/saveNotNull")
    public Result saveSettingOrder(@RequestBody @Valid SettingAndDetails settingAndDetails,BindingResult result){
        if (result.hasErrors()){
            return new Result(400,result.getAllErrors().get(0).getDefaultMessage(),result.getAllErrors());
        }
        return sysTableSettingDetailsService.saveAndUpdateAndDelete3(settingAndDetails);
    }

2.3、数据测试

请求接口发送数据:

{
    "sysTableSettingDTO": {},
    "sysTableSettingDetailsDTOList": []
}

返回结果:

{
    "returnCode": 400,
    "returnMsg": "setting汇总ID不能为null",
    "returnData": [
        {
            "codes": [
                "NotNull.settingAndDetails.sysTableSettingDTO.id",
                "NotNull.sysTableSettingDTO.id",
                "NotNull.id",
                "NotNull.java.lang.Integer",
                "NotNull"
            ],
            "arguments": [
                {
                    "codes": [
                        "settingAndDetails.sysTableSettingDTO.id",
                        "sysTableSettingDTO.id"
                    ],
                    "arguments": null,
                    "defaultMessage": "sysTableSettingDTO.id",
                    "code": "sysTableSettingDTO.id"
                }
            ],
            "defaultMessage": "setting汇总ID不能为null",
            "objectName": "settingAndDetails",
            "field": "sysTableSettingDTO.id",
            "rejectedValue": null,
            "bindingFailure": false,
            "code": "NotNull"
        },
        {
            "codes": [
                "NotEmpty.settingAndDetails.sysTableSettingDetailsDTOList",
                "NotEmpty.sysTableSettingDetailsDTOList",
                "NotEmpty.java.util.List",
                "NotEmpty"
            ],
            "arguments": [
                {
                    "codes": [
                        "settingAndDetails.sysTableSettingDetailsDTOList",
                        "sysTableSettingDetailsDTOList"
                    ],
                    "arguments": null,
                    "defaultMessage": "sysTableSettingDetailsDTOList",
                    "code": "sysTableSettingDetailsDTOList"
                }
            ],
            "defaultMessage": "setting明细List不能为空集合",
            "objectName": "settingAndDetails",
            "field": "sysTableSettingDetailsDTOList",
            "rejectedValue": null,
            "bindingFailure": false,
            "code": "NotEmpty"
        }
    ]
}

三、单个参数校验

参考博客地址

3.1 直接在参数前加上校验注解:

package com.chushiyan.validation_tutorial.controller;

import com.chushiyan.validation_tutorial.entity.Result;
import com.chushiyan.validation_tutorial.pojo.User;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

/**
 * @author chushiyan
 * @email  Y2h1c2hpeWFuMDQxNUAxNjMuY29t(base64)
 * @description
 */
@RestController
@RequestMapping("/user")
@Validated
public class UserController  {

    @GetMapping
    public Result test2(@NotNull(message = "name不能为空")  String name){
        System.out.println(name);
        return new Result(true,200,"");
    }
}

注意:需要在类上添加@Validated注解,否则不会校验。

四、参数校验分组

在实际开发中经常会遇到这种情况:添加用户时,id是由后端生成的,不需要校验id是否为空,但是修改用户时就需要校验id是否为空。如果在接收参数的User实体类的id属性上添加NotNull,显然无法实现。这时候就可以定义分组,在需要校验id的时候校验,不需要的时候不校验。

4.1 定义表示组别的接口类

package com.chushiyan.validation_tutorial.validate;
public interface GroupA {
}

4.2 在实体类的注解中标记id使用上面定义的组

给id属性添加分组:

package com.chushiyan.validation_tutorial.pojo;

import com.chushiyan.validation_tutorial.validate.GroupA;
import lombok.Data;

import javax.validation.constraints.*;
import java.io.Serializable;

/**
 * @author chushiyan
 * @email  Y2h1c2hpeWFuMDQxNUAxNjMuY29t(base64)
 * @description
 */
@Data
public class User implements Serializable {

    @NotNull(groups = GroupA.class, message = "id不能为空")
    private String id;

    @NotNull(message = "姓名不能为空")
    @Size(min = 1, max = 20, message = "姓名长度必须在1-20之间")
    private String name;

    @Min(value = 10, message = "年龄必须大于10")
    @Max(value = 150, message = "年龄必须小于150")
    private Integer age;

    @Email(message = "邮箱格式不正确")
    private String email;
}

4.3 在controller中使用@Validated指定使用哪个组

    @PostMapping
    public Result add(@Validated @RequestBody User user) {
        return new Result(true, 200, "增加用户成功");
    }

    @PutMapping("/update")
    // 指定GroupA,这样就会校验id属性是否为空
    // 注意:还得必须添加Default.class,否则不会执行其他的校验(如我们案例中的@Email)
    public Result update(@Validated({GroupA.class, Default.class}) @RequestBody User user) {
        return new Result(true, 200, "修改用户成功");
    }

Q.E.D.


ALL WILL BE CLEAR