Spring validate参数校验

目录

一.Spring validate 是什么

二.Spring validate的主要功能及作用

三.Spring validate如何使用

1.引入依赖

2.参考实体类

四.三种校验方式,返回的异常类型及方式

1.MethodArgumentNotValidException异常

2.BindException异常

3.ConstraintViolationException异常

五.编写统一异常处理类

六.validate校验注解合集


一.Spring validate 是什么

Spring Validate 是 Spring 框架提供的一个用于数据校验的模块。它提供了一种方便的方式来验证应用程序中的数据,例如用户输入、请求参数等。通过使用 Spring Validate,您可以定义验证规则,并在数据不符合这些规则时抛出异常,从而确保数据的完整性和准确性。

Spring Validate 提供了以下功能:

        注解验证:使用注解来定义验证规则,例如 @NotNull、@Size 等。这些注解可以应用于类、字段或方法上,以便在运行时进行验证。

        自定义验证器:您可以使用自定义验证器来定义自己的验证规则。自定义验证器可以扩展 Spring 的 Validator 接口,并实现 validate() 方法来执行自定义的验证逻辑。

        校验分组:您可以根据不同的需求将校验规则分组,并在运行时选择要应用的组。这对于在不同场景下使用不同的校验规则非常有用。

        错误处理:如果数据不符合验证规则,Spring Validate 将抛出 ConstraintViolationException 异常。您可以使用 @ControllerAdvice 注解和 @ExceptionHandler 方法来处理这些异常,并返回适当的错误消息给用户。

总的来说,Spring Validate 是一个强大的工具,可以帮助您在 Spring 应用程序中确保数据的完整性和准确性。通过使用注解和自定义验证器,您可以轻松地定义验证规则,并在运行时执行这些规则来确保数据的正确性。

二.Spring validate的主要功能及作用

Spring Validate主要功能包括但不限于:

        参数校验:Spring Validate可以用于对Controller层中接收的参数进行校验,包括请求参数、用户输入等。通过注解的方式,可以方便地定义验证规则,例如非空验证、长度验证等。

        数据完整性验证:在数据传输和存储过程中,可能会遇到数据被篡改或损坏的情况。通过Spring Validate对数据进行校验,可以确保数据的完整性和准确性。

        自定义校验规则:如果默认的验证规则不能满足需求,Spring Validate允许自定义校验规则。用户可以扩展验证器接口,实现自定义的验证逻辑。

        错误处理:当数据不符合验证规则时,Spring Validate会抛出异常。通过捕获并处理这些异常,可以在前端页面上展示错误信息,或者在日志中记录错误信息。

        校验分组:可以将校验规则分组,并在运行时选择要应用的组。这可以帮助在不同的场景下使用不同的校验规则。

三.Spring validate如何使用

1.引入依赖

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

2.参考实体类

以下是带有大部分验证注解的参考实体类

@Data
public class Student {

    /**
     * 学生姓名
     * - 不允许为空
     * - 长度必须在2到30个字符之间
     */
    @NotNull(message = "姓名不能为空")
    @Size(min = 2, max = 30, message = "姓名长度必须在2到30个字符之间")
    private String name;

    /**
     * 学生邮箱
     * - 必须是有效的电子邮件地址
     * - 不允许为空
     */
    @Email(message = "邮箱地址格式不正确")
    @NotEmpty(message = "邮箱不能为空")
    private String email;

    /**
     * 学生年龄
     * - 必须在18到100岁之间
     */
    @Min(value = 18, message = "年龄必须至少18岁")
    @Max(value = 100, message = "年龄必须不超过100岁")
    private int age;

    /**
     * 学生用户名
     * - 必须是5到10个字母数字字符
     */
    @Pattern(regexp = "^[a-zA-Z0-9]{5,10}$", message = "用户名必须是5到10个字母数字字符")
    private String username;

    /**
     * 学生金额
     * - 必须在0.01到1000.00之间
     */
    @DecimalMin(value = "0.01", message = "金额必须至少0.01")
    @DecimalMax(value = "1000.00", message = "金额必须不超过1000.00")
    private BigDecimal amount;

    /**
     * 学生激活状态
     * - 必须为true
     */
    @AssertTrue(message = "激活状态必须为true")
    private boolean active;

    /**
     * 学生删除状态
     * - 必须为false
     */
    @AssertFalse(message = "删除状态必须为false")
    private boolean deleted;

    /**
     * 学生开始日期
     * - 必须在将来
     */
    @Future(message = "开始日期必须在将来")
    private Date startDate;

    /**
     * 学生出生日期
     * - 必须在过去
     */
    @Past(message = "出生日期必须在过去")
    private Date birthDate;

    /**
     * 学生预约日期
     * - 必须在将来或今天
     */
    @FutureOrPresent(message = "预约日期必须在将来或今天")
    private LocalDate appointmentDate;

    /**
     * 学生注册日期
     * - 必须在过去或今天
     */
    @PastOrPresent(message = "注册日期必须在过去或今天")
    private LocalDate registrationDate;
    
}

注: 以下是常用于非空判断的注解及区别

@NotNull:适用于任何类型,不能为null,但可以是 ("")

@NotBlank:只能用于 String,不能为null,而且调用 trim() 后,长度必须大于0,必须要有实际字符。

@NotEmpty:用于 String、Collection、Map、Array,不能为null,长度必须大于0。

四.三种校验方式,返回的异常类型及方式

1.MethodArgumentNotValidException异常

在需要校验的对象前面加 @RequestBody注解以及@Validated或者@Valid注解,如果校验失败,会抛出MethodArgumentNotValidException异常

@RestController
public class VerifyController {
    @PostMapping("save")
    public void save(@RequestBody @Validated Student student) {
        System.out.println("校验失败,会抛出MethodArgumentNotValidException异常");
    }
}

2.BindException异常

在需要校验的对象前面加@RequestBody注解,使用@Validated或者@Valid注解,如果校验失败,会抛出BindException异常

@RestController
public class VerifyController {
    @PostMapping("save")
    public void save(@Validated Student student) {
        System.out.println("校验失败,会抛出BindException异常");
    }
}

3.ConstraintViolationException异常

路径传参,在参数前面加上相对应的校验注解,还必须在Controller类上加 @Validated注解。如果校验失败,会抛出ConstraintViolationException异常

/**
 * 控制器类,用于处理保存用户信息的请求。
 * 使用了 {@link Validated} 注解来启用参数验证。
 */
@RestController
@Validated
public class VerifyController {
    /**
     * 处理保存用户信息的 POST 请求。
     * 该方法接收两个请求参数:`name` 和 `age`。
     *
     * @param name 用户名,使用 {@link NotBlank} 注解确保其不为空或只包含空白字符。
     *             如果 `name` 为空或只包含空白字符,会抛出 {@link ConstraintViolationException} 异常。
     * @param age 用户年龄,使用 {@link NotNull} 注解确保其不为 null。
     *            如果 `age` 为 null,会抛出 {@link ConstraintViolationException} 异常。
     */
    @PostMapping("save")
    public void save(@NotBlank(message = "name不能为空") String name, @NotNull(message = "age不能为空") Integer age) {
        System.out.println("校验失败,会抛出ConstraintViolationException异常");
    }
}

注: 请求路径类似于: http://localhost:8080/save?name=&age=25

五.编写统一异常处理类

@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理 {@link MethodArgumentNotValidException} 异常。
     * 当请求体(@RequestBody)中的数据验证失败时,会抛出此异常。
     * 该方法会从异常中提取所有验证错误信息,并返回一个包含所有错误信息的字符串。
     *
     * @param e MethodArgumentNotValidException 异常对象
     * @return 包含所有验证错误信息的字符串
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public String handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        String messages = bindingResult.getAllErrors()
                .stream()
                .map(ObjectError::getDefaultMessage)
                .collect(Collectors.joining(";"));
        return messages;
    }

    /**
     * 处理 {@link BindException} 异常。
     * 当表单数据绑定失败或验证失败时,会抛出此异常。
     * 该方法会从异常中提取所有验证错误信息,并返回一个包含所有错误信息的字符串。
     *
     * @param e BindException 异常对象
     * @return 包含所有验证错误信息的字符串
     */
    @ExceptionHandler(value = BindException.class)
    public String exceptionHandler(BindException e) {
        String messages = e.getBindingResult().getAllErrors()
                .stream()
                .map(ObjectError::getDefaultMessage)
                .collect(Collectors.joining(";"));
        return messages;
    }

    /**
     * 处理 {@link ConstraintViolationException} 异常。
     * 当请求参数(@RequestParam)上的数据验证失败时,会抛出此异常。
     * 该方法会从异常中提取所有验证错误信息,并返回一个包含所有错误信息的字符串。
     *
     * @param exception ConstraintViolationException 异常对象
     * @return 包含所有验证错误信息的字符串
     */
    @ExceptionHandler({ConstraintViolationException.class})
    public String methodArgumentNotValid(ConstraintViolationException exception) {
        String message = exception.getConstraintViolations().stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.joining(";"));
        return message;
    }
}

六.validate校验注解合集

注解

解释

适用类型

null值有效

示例

@AssertFalse

验证元素值是

false

boolean,

Boolean

@AssertFalse(message = "必须为 false") private boolean active;

@AssertTrue

验证元素值是

true

boolean,

Boolean

@AssertTrue(message = "必须为 true") private boolean active;

@DecimalMax(value)

验证

BigDecimal、BigInteger、

long、Long、int、

Integer、short、Short、

byte、Byte、double、

Double、float、Float

值小于等于给定的最大值

String,

BigDecimal,BigInteger,

long,Long,int,

Integer,short,Short,

byte,Byte,double,

Double,float,Float

@DecimalMax(value = "100", message = "不能超过100") private int age;

@DecimalMin(value)

验证

BigDecimal、BigInteger、

long、Long、int、

Integer、short、Short、

byte、Byte、double、

Double、float、Float

值大于等于给定的最小值

String,

BigDecimal,BigInteger,

long,Long,int,

Integer,short,Short,

byte,Byte,double,

Double,float,Float

@DecimalMin(value = "18", message = "不能低于18") private int age;

@Digits(integer, fraction)

验证

BigDecimal、

BigInteger、long、Long、

int、Integer、short、

Short、byte、Byte

值的整数部分和小数部分的位数

String,BigDecimal,

BigInteger,long,Long,

int,Integer,short,

Short,byte,Byte

@Digits(integer=3, fraction=2, message = "最多3位整数和2位小数") private BigDecimal price;

@Email

验证元素值是有效的电子邮件地址

CharSequence

@Email(message = "无效的电子邮件地址") private String email;

@Future

验证

Date、Calendar、Temporal

值是在未来的时间

java.util.Date,

java.util.Calendar,

java.time.Temporal

@Future(message = "必须是未来的日期") private LocalDate dateOfBirth;

@FutureOrPresent

验证

Date、Calendar、Temporal

值是在未来或当前的时间

java.util.Date,

java.util.Calendar,

java.time.Temporal

@FutureOrPresent(message = "必须是未来或当前的日期") private LocalDate startDate;

@Max(value)

验证

BigDecimal、BigInteger、

long、Long、int、

Integer、short、Short、

byte、Byte、double、

Double、float、Float

值小于等于给定的最大值

long,Long,int,

Integer,short,Short,

byte,Byte,double,

Double,float,Float

@Max(value = 100, message = "不能超过100") private int age;

@Min(value)

验证

BigDecimal、BigInteger、

long、Long、int、

Integer、short、Short、

byte、Byte、double、

Double、float、Float

值大于等于给定的最小值

long,Long,int,

Integer,short,Short,

byte,Byte,double,

Double,float,Float

@Min(value = 18, message = "不能低于18") private int age;

@Negative

验证

BigDecimal、BigInteger、

long、Long、int、

Integer、short、Short、

byte、Byte、double、

Double、float、Float

值小于零

BigDecimal,BigInteger,

long,Long,int,

Integer,short,Short,

byte,Byte,double,

Double,float,Float

@Negative(message = "必须小于0") private int value;

@NegativeOrZero

验证

BigDecimal、BigInteger、

long、Long、int、

Integer、short、Short、

byte、Byte、double、

Double、float、Float

值小于等于零

BigDecimal,BigInteger,

long,Long,int,

Integer,short,Short,

byte,Byte,double,

Double,float,Float

@NegativeOrZero(message = "必须小于等于0") private int value;

@NotNull

验证元素值不为

null

任何类型

@NotNull(message = "不能为空") private String name;

@Null

验证元素值为

null

任何类型

@Null(message = "必须为 null") private String name;

@Past

验证

Date、Calendar、Temporal

值是在过去的时间

java.util.Date,

java.util.Calendar,

java.time.Temporal

@Past(message = "必须是过去的日期") private LocalDate dateOfBirth;

@PastOrPresent

验证

Date、Calendar、Temporal

值是在过去或当前的时间

java.util.Date,

java.util.Calendar,

java.time.Temporal

@PastOrPresent(message = "必须是过去或当前的日期") private LocalDate startDate;

@Pattern(regexp)

验证元素值符合正则表达式

CharSequence

@Pattern(regexp="^[a-zA-Z0-9]+$", message = "只能包含字母和数字") private String code;

@Positive

验证

BigDecimal、

BigInteger、long、

Long、int、Integer、

short、Short、byte、

Byte、double、

Double、float、Float

值大于零

BigDecimal,BigInteger,

long,Long,int,

Integer,short,Short,

byte,Byte,double,

Double,float,Float

@Positive(message = "必须大于0") private int value;

@PositiveOrZero

验证

BigDecimal、BigInteger、

long、Long、int、

Integer、short、Short、

byte、Byte、double、

Double、float、Float

值大于等于零

BigDecimal,BigInteger,

long,Long,int,

Integer,short,Short,

byte,Byte,double,

Double,float,Float

@PositiveOrZero(message = "必须大于等于0") private int value;

@Size(min, max)

验证集合、数组、字符串的长度在给定范围内

CharSequence,

Collection,Map, 数组

@Size(min=2, max=10, message = "长度必须在2到10之间") private List items;

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值