Spring Validation框架

关于Spring Validation

Spring Validation是用于检查参数的基本格式有效性的框架

在项目中添加spring-boot-starter-validation依赖项:

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

提示:在学习时,为了更清楚的了解执行过程,建议暂时不启用全局异常处理器!

检查POJO类型的参数

在需要被检查的参数前添加@Validated或@Valid注解,表示需要检查此参数,例如:

@PostMapping("/add-new")
//                       ↓↓↓↓↓↓ 新增注解
public JsonResult addNew(@Valid AlbumAddNewDTO albumAddNewDTO) {
    // 
}

然后,在POJO类型的属性上使用“检查注解”(例如:@NotNull表示“不允许为null”)来配置检查规则,例如:

@Data
public class AlbumAddNewDTO implements Serializable {

    @NotNull // 新增注解
    private String name;
    
    // 暂不关心其它代码
    
}

当客户端提交的请求中不包含name属性时,服务器端将响应400错误!并且,在服务器端的控制台会有以下警告信息:

2023-02-24 14:42:16.018  WARN 22020 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors<EOL>Field error in object 'albumAddNewDTO' on field 'name': rejected value [null]; codes [NotNull.albumAddNewDTO.name,NotNull.name,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [albumAddNewDTO.name,name]; arguments []; default message [name]]; default message [不能为null]]

处理检查失败时异常

当检查失败时,Spring Validation框架会抛出BindException,同时,此框架还有DefaultHandlerExceptionResolver对此异常进行处理,以至于默认的失败效果是响应400错误。

可以在全局异常处理器中添加处理BindException异常的方法:

@ExceptionHandler
public JsonResult handleBindException(BindException e) {
    String message = "请求参数格式错误!!!";
    return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST, message);
}

在处理异常时,应该对错误的原因进行更加精准的描述,此描述文本需要通过检查注解的message属性进行配置,例如:

@Data
public class AlbumAddNewDTO implements Serializable {

    @NotNull(message = "必须填写相册名称!") // 配置注解参数
    private String name;
    
    // 暂不关心其它代码
    
}

然后,在处理异常时,可以通过BindException对象的getFieldError().getDefaultMessage()获取此信息,例如:

@ExceptionHandler
public JsonResult handleBindException(BindException e) {
    String message = e.getFieldError().getDefaultMessage();
    return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST, message);
}

但是,当同时存在多种错误时,以上处理方式只能提示多种错误中的某1种,如果需要提示全部错误,需要调整为:

@ExceptionHandler
public JsonResult handleBindException(BindException e) {
    StringBuilder stringBuilder = new StringBuilder();
    List<FieldError> fieldErrors = e.getFieldErrors();
    for (FieldError fieldError : fieldErrors) {
        stringBuilder.append(fieldError.getDefaultMessage());
    }
    String message = stringBuilder.toString();

    return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST, message);
}

关于快速失败

快速失败表现为:当检查参数的格式不通过时,不再继续对其它参数的检查!

相关配置代码如下:

package cn.tedu.csmall.product.config;

import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.validation.Validation;

/**
 * Validation配置类
 *
 * @author java@tedu.cn
 * @version 0.0.1
 */
@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对象
    }

}

检查简单类型参数

当需要检查简单类型的参数时,需要先在当前类上添加@Validated注解,例如:

@RestController
@RequestMapping("/album")
@Validated // 新增
public class AlbumController {
    // 暂不关心
}

然后,在需要检查的参数上添加检查注解,例如:

@PostMapping("/delete")
//                                     ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 检查注解的配置
public JsonResult delete(@RequestParam @Range(min = 1) Long id) {
    albumService.delete(id);
    return JsonResult.ok();
}

提示:以上参数上的@RequestParam只是临时使用的,如果没有此注解,在API文档的调试界面中暂时无法显示参数的输入框。

当提交的请求参数id值小于1时,会响应500错误,并且在服务器端的控制台会提示错误,例如:

javax.validation.ConstraintViolationException: delete.id: 需要在1和9223372036854775807之间

则可以在全局异常处理器中添加处理以上异常的方法:

@ExceptionHandler
public JsonResult handleConstraintViolationException(ConstraintViolationException e) {
    StringBuilder stringBuilder = new StringBuilder();
    Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
    for (ConstraintViolation<?> constraintViolation : constraintViolations) {
        stringBuilder.append(constraintViolation.getMessage());
    }
    String message = stringBuilder.toString();
    return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST, message);
}

常用检查注解

使用Spring Validation框架时,常用的检查注解有:

  • @NotNull:不允许为null值,即客户端必须提交此参数

  • @NotEmpty:不允许为空值,即长度为0的字符串

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

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

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

  • @Pattern:通过此注解的regexp属性指定正则表达式,检查参数是否匹配此正则表达式

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

  • @Range:限制数值型的参数值的有效区间

  • 仅能作用于数值型的参数

以上2个注解可以同时添加在1个参数上。

以上@Range仅当参数值存在时执行检查,如果调用此方法时,传入的参数值为null,则此注解是无效的!所以,这类注解通常与@NotNull一起使用!

在源代码中,按住Ctrl键点击检查注解所在的包

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值