从零搭建 Spring MVC 项目 —— Validation

快速开始

1. 引入 Validation 依赖


    org.springframework.boot
    spring-boot-starter-validation

2. 编写校验代码

@Data 为 lombok 的注解,在此不做详细说明。
@Data
public class UserRequest {

    @NotBlank
    private String name;

    @Min(0)
    @Max(200)
    private Integer age;

}

3. 声明校验参数

@RestController
public class UserController {

    @PostMapping("/api/users")
    public UserRequest createUser(@RequestBody @Validated UserRequest userRequest) {
        return userRequest;
    }

}

4. 捕捉全局异常

这一步不是必须的,目的是为了能方便查看校验结果。
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity> handleMethodArgumentNotValidException(
            MethodArgumentNotValidException exception) {
        List errorMessages = exception.getFieldErrors()
                .stream()
                .map(fieldError -> String.format("%s %s", fieldError.getField(), 
                        fieldError.getDefaultMessage()))
                .sorted()
                .collect(Collectors.toList());

        Map errorMessageMap = CollectionUtils.newLinkedHashMap(2);
        errorMessageMap.put("code", HttpStatus.BAD_REQUEST.value());
        errorMessageMap.put("message", errorMessages);

        return ResponseEntity.badRequest().body(errorMessageMap);
    }

}

5. 查看校验效果

使用 curl 访问接口:

curl --location --request POST 'http://localhost:8080/api/users' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "",
    "age": -1
}'

最终的校验结果如下:

{
    "code": 400,
    "message": [
        "age 最小不能小于0",
        "name 不能为空"
    ]
}

常用注解

@NotNull、@NotEmpty 与 @NotBlank

注解 作用对象 含义
@NotNull 可以作用于任意对象 对象不能为 null
@NotEmpty 只能作用于 String、Collection、Map 和数组 对象不能为 null ,且对象的长度不能为 0
@NotBlank 只能作用于 String 字符串不能为 null ,且字符串的长度不能为 0

示例代码:

@Data
public class NotAnnotationRequest {

    @NotNull
    private Object notNullObject;

    @NotEmpty
    private String notEmptyString;

    @NotEmpty
    private Collection notEmptyCollection;

    @NotEmpty
    private Map notEmptyMap;

    @NotEmpty
    private int[] notEmptyArray;

    @NotBlank
    private String notBlankString;

}

@Size 与 @Min、@Max

注解 作用对象 含义
@Size 可以作用于 String、Collection、Map 和数组 包含两个变量:min 和 max,其中 min 的默认值为 0 ,表示对象的最小长度;max 的默认值为 Integer.MAX_VALUE ,表示对象的最大长度
@Min 可以作用于 BigDecimal、BigInteger,byte、short、int、long 以及它们的包装类型 表示数字的最小值
@Max 可以作用于 BigDecimal、BigInteger,byte、short、int、long 以及它们的包装类型 表示数字的最大值

示例代码:

@Data
public class RangeAnnotationRequest {

    @Size(min = 1, max = 5)
    private String limitedString;

    @Size(min = 1, max = 5)
    private Collection limitedCollection;

    @Size(min = 1, max = 5)
    private Map limitedMap;

    @Size(min = 1, max = 5)
    private int[] limitedArray;

    @Min(1)
    @Max(2)
    private Integer limitedNumber;

}

@Pattern

参数 含义
regexp 正则表达式
flags 标识正则表达式的模式,包含:
Pattern.Flag.UNIX_LINES、
Pattern.Flag.CASE_INSENSITIVE、
Pattern.Flag.COMMENTS、
Pattern.Flag.MULTILINE、
Pattern.Flag.DOTALL、
Pattern.Flag.UNICODE_CASE、
Pattern.Flag.CANON_EQ
共7种模式
message 错误提示信息(message 不是 @Pattern 特有的,所有 Validation 注解都包含该参数)

示例代码:

@Data
public class PatternAnnotationRequest {

    @Pattern(regexp = "^1[3456789]\\d{9}$", message = "手机号码格式不正确")
    private String mobile;

}

@Valid 与 @Validated

@Valid 和 @Validated 都可以用来声明校验参数,但它们并不完全一样,它们的区别主要包含以下几个方面:

  • @Valid 是定义在 javax 包下的标准注解,@Validated 是 Spring 官方定义的注解。
  • @Valid 可以作用于方法、字段、构造函数、参数和运行时使用的类型,@Validated 可作用于类型、方法和参数。
  • @Valid 可以用来定义嵌套校验,@Validated 无法单独完成嵌套校验的定义。
  • @Validated 支持分组校验,@Valid 不支持分组校验。

使用 @Valid 声明校验参数

@RestController
public class UserController {

    @PostMapping("/api/users")
    public UserRequest createUser(@RequestBody @Valid UserRequest userRequest) {
        return userRequest;
    }

}

嵌套校验

编写校验代码:

@Data
public class CompanyRequest {

    @NotBlank
    private String name;

    @Valid
    @NotNull
    private AddressRequest address;

}
@Data
public class AddressRequest {

    @NotBlank
    private String country;

    @NotBlank
    private String province;

    @NotBlank
    private String city;

}

声明校验参数:

@RestController
public class NestValidController {

    @PostMapping("/api/companies")
    public CompanyRequest createCompany(@RequestBody @Validated CompanyRequest companyRequest) {
        return companyRequest;
    }

}

分组校验

定义分组:

public interface CreateGroup extends Default {
}
public interface UpdateGroup extends Default {
}

编写校验代码:

@Data
public class OrganizationRequest {

    @NotBlank(groups = CreateGroup.class)
    @Null(groups = UpdateGroup.class)
    private String orgCode;

    @NotBlank
    private String orgName;

}

声明校验参数:

@RestController
public class GroupValidController {

    @PostMapping("/api/organizations")
    public OrganizationRequest createOrganization(
            @RequestBody @Validated(CreateGroup.class) OrganizationRequest organizationRequest) {
        return organizationRequest;
    }

    @PutMapping("/api/organizations")
    public OrganizationRequest updateOrganization(
            @RequestBody @Validated(UpdateGroup.class) OrganizationRequest organizationRequest) {
        return organizationRequest;
    }

}

其他注解

@Null

注解 作用对象 含义
@Null 可以作用于任意对象 对象必须为 null

示例代码:

@Data
public class NullAnnotationRequest {

    @Null
    private Object nullObject;

}

@Email

注解 作用对象 含义
@Email 只能作用于 String 字符串必须为合法的 email

示例代码:

@Data
public class EmailAnnotationRequest {

    @Email
    private String email;

}

布尔类型注解

注解 作用对象 含义
@AssertTrue 可以作用于 boolean 和 Boolean 对象必须为 true
@AssertFalse 可以作用于 boolean 和 Boolean 对象必须为 false

示例代码:

@Data
public class BooleanAnnotationRequest {

    @AssertTrue
    private Boolean trueParam;

    @AssertFalse
    private boolean falseParam;

}

数字类型注解

注解 作用对象 含义
@DecimalMin 可以作用于数字类型和字符串 表示数字的最小值
@DecimalMax 可以作用于数字类型和字符串 表示数字的最大值
@Digits 可以作用于数字类型和字符串 包含两个变量:integer 和 fraction,其中 integer 表示整数位的最大位数;fraction 表示小数位的最大位数
@Negative 可以作用于数字类型 表示必须为负数
@NegativeOrZero 可以作用于数字类型 表示必须为负数或零
@Positive 可以作用于数字类型 表示必须为正数
@PositiveOrZero 可以作用于数字类型 表示必须为正数或零

示例代码:

@Data
public class NumberAnnotationRequest {

    @DecimalMin("1.5")
    @DecimalMax("2.5")
    private BigDecimal limitedBigDecimal;

    @Digits(integer = 1, fraction = 2)
    private BigDecimal digits;

    @Negative
    private short negative;

    @NegativeOrZero
    private int negativeOrZero;

    @Positive
    private long positive;

    @PositiveOrZero
    private BigDecimal positiveOrZero;

}

时间类型注解

注解 作用对象 含义
@Past 可以作用于时间类型 表示必须为过去的时间
@PastOrPresent 可以作用于时间类型 表示必须为过去的时间或现在
@Future 可以作用于时间类型 表示必须为将来的时间
@FutureOrPresent 可以作用于时间类型 表示必须为将来的时间或现在

示例代码:

@Data
public class TimeAnnotationRequest {

    @Past
    private Date past;

    @PastOrPresent
    private Date pastOrPresent;

    @Future
    private Date future;

    @FutureOrPresent
    private Date futureOrPresent;

}

获取源码

你可能感兴趣的:(spring-mvc)