[SpringBoot]Spring Validation框架

文章介绍了SpringValidation框架如何用于检查方法参数的有效性,包括添加依赖、校验封装和未封装的请求参数,处理BindException异常,以及使用各种验证注解如@NotNull、@Range等。还探讨了如何在全局异常处理器中优雅地处理验证失败的情况。
摘要由CSDN通过智能技术生成

目录

关于Spring Validation

添加依赖

检查封装的请求参数

处理BindException

检查未封装的请求参数

检查注解


关于Spring Validation

 Spring Validation框架的主要作用是检查方法的参数的基本有效性。

 

添加依赖

此框架的依赖项的artifactId为:spring-boot-starter-validation

<!-- Spring Boot支持Spring Validation用于检查方法参数的基本有效性的依赖项 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>${spring-boot.version}</version>
</dependency>

检查封装的请求参数

需要先在方法的参数(封装的类型)前添加@Valid@Validated注解,以表示“将检查此参数的基本有效性”,例如:

@PostMapping("/add-new")
public String addNew(@Valid AlbumAddNewParam albumAddNewParam) {
    albumService.addNew(albumAddNewParam);
    return "添加成功!";
}

然后,需要在封装的类型的属性上添加检查注解,以配置对应的检查规则,例如:

@Data
public class AlbumAddNewParam implements Serializable {

    @NotNull
    private String name;
    
}

经过以上配置,参数name将不允许为null值(空字符串不是null),如果客户端提交的请求中没有name的值,将直接响应400错误!

 

处理BindException

当检查参数的基本有效性不通过时,在服务器端的控制台会提示错误详情,例如:

2023-05-11 14:25:21.058  WARN 45924 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors

Field error in object 'albumAddNewParam' on field 'name': rejected value [null]; codes [NotNull.albumAddNewParam.name,NotNull.name,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [albumAddNewParam.name,name]; arguments []; default message [name]]; default message [不能为null]]

检查注解还可以配置message属性,用于指定检查不通过时的文本信息,例如:

@NotNull(message = "添加相册失败,必须提交相册名称!")
private String name;

 经过以上配置后,如果检查失败,错误信息大致如下:

Field error in object 'albumAddNewParam' on field 'name': rejected value [null]; codes [NotNull.albumAddNewParam.name,NotNull.name,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [albumAddNewParam.name,name]; arguments []; default message [name]]; default message [添加相册失败,必须提交相册名称!]

 然后,需要在全局异常处理器中添加处理BindException请求的方法:
 以下当有多个检查都不通过时,解决方案1是随机显示一个不通过时的文本信息

 解决方案2是拼接显示多个不通过时的文本信息
StringJoiner相当于StringBuilder,不同的是它可以加分割符,和前缀以及后缀(它有两款构造方法,一个是只加分隔符,一个是加分隔符前缀后缀)

 

  解决方案3是通过集合得到数组形式的不通过时的文本信息

 

 

@ExceptionHandler
public String handleBindException(BindException e) {
    log.warn("程序运行过程中出现了BindException,将统一处理!");
    log.warn("异常信息:{}", e.getMessage());
    // 【解决方案-1】使用1个字符串表示1个错误信息
    String message = e.getFieldError().getDefaultMessage();
    return message;

    // 【解决方案-2】使用1个字符串表示错误信息
    // StringJoiner stringJoiner = new StringJoiner(",", "请求参数错误,", "!");
    // List<FieldError> fieldErrors = e.getFieldErrors();
    // for (FieldError fieldError : fieldErrors) {
    //    String defaultMessage = fieldError.getDefaultMessage();
    //    stringJoiner.add(defaultMessage);
    // }
    // return stringJoiner.toString();

    // 【解决方案-3】使用集合表示多个错误信息,需要将当前方法的返回值类型声明为对应的集合类型
    // List<String> messageList = new ArrayList<>();
    // List<FieldError> fieldErrors = e.getFieldErrors();
    // for (FieldError fieldError : fieldErrors) {
    //    String defaultMessage = fieldError.getDefaultMessage();
    //    messageList.add(defaultMessage);
    // }
    // return messageList;
}

需要注意:Spring Validation在检查请求参数的格式时,会检查所有属性配置的规则,找出所有的错误,如果希望实现“只要发现错误,就不再向后检查”,需要将其配置为“快速失败”,配置做法是使用配置类(比如在上面选择方案一的时候就不会随机显示了):

@Slf4j
@Configuration
public class ValidationConfiguration {

    public ValidationConfiguration() {
        log.debug("创建配置类对象:ValidationConfiguration");
    }

    @Bean
    public javax.validation.Validator validator() {
        return Validation.byProvider(HibernateValidator.class)
                .configure() // 开始配置
                .failFast(true) // 配置快速失败
                .buildValidatorFactory() // 构建Validator工厂
                .getValidator(); // 从Validator工厂中获取Validator对象
    }

}

 

检查未封装的请求参数

 对于未封装的请求参数(例如参数列表中的`Long id`)的检查,需要先在当前方法所在的类上添加`@Validated`注解,例如:

@RestController
@RequestMapping("/album")
@Validated
public class AlbumController {
}

然后,在参数上添加对应的检查注解,例如:
min的默认最小值是0,设置为1,代表最小id值为1。最大值是默认很大不需要设置。
(这里加 @RequestParam是为了api文档有输入框,迎合它的bug,没有其他作用,以后是要去掉的)

@PostMapping("/delete")
public String delete(@Range(min = 1, message = "根据ID删除相册失败,请提交合法的ID值!") 
                     @RequestParam Long albumId) throws Exception {
    // ...
}

暂时不使用全局异常处理器,当提交的请求参数不符合以上配置的规则时,在服务器的控制台可以看到错误信息:

javax.validation.ConstraintViolationException: delete.albumId: 根据ID删除相册失败,请提交合法的ID值!

则需要在全局异常处理器中添加处理以上异常:

@ExceptionHandler
public String handleConstraintViolationException(ConstraintViolationException e) {
    log.warn("程序运行过程中出现了ConstraintViolationException,将统一处理!");
    log.warn("异常信息:{}", e.getMessage());
    String message = null;
    Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
    for (ConstraintViolation<?> constraintViolation : constraintViolations) {
        message = constraintViolation.getMessage();
    }
    return message;

检查注解

 在org.hibernate.validator.constraintsjavax.validation.constraints这2个包中的都是检查注解!

 常用的检查注解有:

  • @NotNull:不允许为null

    • 可以用于任何类型

  • @NotEmpty:不允许为空字符串(长度为0的字符串),并且会检查是否为null值(为null时报错)

    • 仅能用于字符串类型的参数

  • @NotBlank:不允许为空白,即不允许是“仅由空格、TAB等空白值组成的字符串”

    • 仅能用于字符串类型的参数

  • @Range:通过配置minmax属性来限制数值类型参数的值区间,它不会检查是否为null(为null并不执行任何检查,且不会报错)

    • 仅能用于整型参数

  • @Pattern:通过配置regexp属性来配置正则表达式

    • 仅能用于字符串类型的参数

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值