Spring Boot 整合 Hibernate Validator

本贴最后更新于 2110 天前,其中的信息可能已经斗转星移

Spring Boot 整合 Hibernate Validator


Hibernate Validator 提供了对请求参数的校验,方便我们在开发中管理校验信息。本文通过简单的示例描述在 Spring Boot 项目中使用 Hibernate Validator。(本文仅描述 Spring Boot 如何使用,不再单独展示单独使用的说明,如果需要了解更多信息,可以参考官方文档

在 Spring Boot 的 web 包中已经为我们引入了 Validator 的依赖,所以不再需要添加额外的依赖包,直接就可以使用。

一、校验模式

Validator 提供两种校验模式:普通校验模式快速校验模式

  • 普通校验模式:普通校验模式会一次性校验所有参数,并返回所有不符合要求的错误信息。
  • 快速校验模式:快速校验模式在校验过程中,当遇到第一个不满足条件的参数时就立即返回,不再继续后面参数的校验。

二、配置

在 Spring Boot 中使用 Validator 需要注意一个问题。默认情况下在控制器中通过使用 @Valid 注解和校验模型只能在 POST 请求中生效,GET 请求没有效果。所以,在配置时,我们需要用到 Spring 对 Validator 的拓展。配置信息如下:

@Configuration
public class ValidatorConfiguration {
    
    //配置1
    @Bean
    public Validator validator() {
        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
                .configure()
                .addProperty("hibernate.validator.fail_fast", "true") //快速验证模式,有第一个参数不满足条件直接返回
                .buildValidatorFactory();
        return validatorFactory.getValidator();
    }

    //配置2
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
        postProcessor.setValidator(validator());
        return postProcessor;
    }

}

配置 1 是 Validator 的默认配置,而配置 2 则是对默认配置的拓展,解决了 GET 请求参数的校验。同时,在校验模式上直接使用快速校验,只要满足一个参数不符合就立即返回错误信息。如果所有信息都返回,则取消配置即可。

三、错误信息处理

在 Validator 配置中,默认的错误返回方式是通过 BindingResult 对象进行返回的,而在 Spring 拓展中是通过 ConstraintViolation 集合返回,对应的异常信息也不一样。
在 web 项目中,参数校验异常信息都需要经过自定义处理,封装成统一的格式进行输出。定义全局异常处理并捕获对应的异常进行处理是比较通用的一种方式。代码实现如下:

@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 未被关注的异常信息,统一返回给客户端为“系统异常”
     *
     * @param e
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public JSONResult handler(RuntimeException e) {
        e.printStackTrace();
        return new JSONResult(-1, "系统异常");
    }

    /**
     * Hibernate Validator参数校验异常处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public JSONResult handler(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        ObjectError objectError = bindingResult.getAllErrors().get(0);
        return new JSONResult(-1, objectError.getDefaultMessage());
    }

    /**
     * Spring Validator参数校验异常处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public JSONResult handler(ConstraintViolationException e) {
        Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
        for (ConstraintViolation<?> constraintViolation : constraintViolations) {
            String message = constraintViolation.getMessage();
            if (!StringUtils.isEmpty(message)) {
                //直接返回第一个错误信息
                return new JSONResult(-1, message);
            }
        }
        return new JSONResult(-1, "参数错误");
    }
}

由于采用的快速校验模式,在处理异常时直接返回第一个错误信息即可。

四、校验模型和参数定义

  • POST 请求

post 请求中我们需要定义一个校验模型,并配置 @Valid 注解进行使用。

public class UserLoginDto implements Serializable {

    //账号
    @NotBlank(message = "账号不能为空")
    private String username;

    //验证码
    @NotBlank(message = "验证码不能为空")
    private String code;
    
    //Getter Setter...
}
  @PostMapping(value = "/login")
    public User login(@RequestBody @Valid UserLoginDto account) {
        //do ...
        return null;
    }
  • GET 请求
    get 请求中稍有变化。
  @GetMapping(value = "/info")
    public JSONResult userInfo(@NotEmpty(message = "ID不能为空") String userId) {
        //do ...
        return JSONResult.result(null);
    }

除了在参数中需要定义特定的注解信息以外,还需要在控制器类名上加上 @Validated 注解配置使用。此处只是做简单的示例,以下为常用注解:

@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
Hibernate Validator 附加的 constraint
@NotBlank(message =) 验证字符串非 null,且长度必须大于 0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内

以上就是 Validator 在 Spring Boot 中的简单使用,实际功能远不止这些,具体情况建议参考官方文档。

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3190 引用 • 8214 回帖 • 1 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    943 引用 • 1460 回帖 • 3 关注
  • validator
    3 引用

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...