SpringMVC校验注解不生效

简介

SpringMVC框架提供了SPI扩展:javax.validation.spi.ValidationProvider,用来实现参数校验功能。Spring使用hibernate-validator作为它的默认实现,我们只需要进行一些简单的注解声明,就可以达到参数校验的功能。但是在实际使用场景中,经常会出现校验没生效的问题。

原因分析

  1. 检查jar包依赖。
    需要确报项目引入hibernate-validator以及与之匹配的validation-api版本,推荐直接依赖spring-boot-starter-validation
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

最好检查下pom实际生效的依赖,有可能因为项目中显示引入了这两个包或者其他包间接依赖了这两个包导致他们版本不匹配。hibernate-validator依赖的validator-api才是它支持的版本。

  1. 检查注解是否正确
    新版本J2EE已经把javax包改成了jarkata包,检查项目中的validation-api中校验注解的包路径,选择与之匹配的注解。
    javax.validation.constraints.NotNull, jakarta.validation.constraints.NotNull

  2. 检查方法签名中,参数签名是否加了@Valid注解,必须加了@Valid注解的参数才会被校验。

  3. 检查参数是不是List类型,目前List不会被校验。

  4. 检查复杂字段上是否有@Valid注解,成员变量如果不是基本类型,需要在上面使用@Valid注解。

  5. 其他情况可以打断点排查:org.hibernate.validator.internal.engine.ValidatorImpl#validate

解决方案

对于参数是List类型,需要自己新建一个ValidationUtil类,在方法开始处手动调用校验。

public class ValidationUtil {
   

    private static final Validator validator;

    static {
   
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    public static void validate(Object object, String objectName) {
   
        if (object instanceof List) {
   
            for (Object obj : (List<?>) object) {
   
                validateEntity(obj, objectName);
            }
        } else {
   
            validateEntity(object, objectName);
        }
    }

	@SneakyThrows
    private static void validateEntity(Object object, String objectName) {
   
        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object);
        if (!constraintViolations.isEmpty()) {
   
            throw new MethodArgumentNotValidException(null, createBindingResult(constraintViolations, objectName));
        }
    }

    private static BindingResult createBindingResult(Set<ConstraintViolation<Object>> violations, String objectName) {
   
        List<FieldError> fieldErrors = new ArrayList<>();

        for (ConstraintViolation<Object> violation : violations) {
   
            FieldError fieldError = new FieldError(
                    objectName,
                    violation.getPropertyPath().toString(),
                    violation.getMessage()
            );
            fieldErrors.add(fieldError);
        }

        return new BeanPropertyBindingResult(null, objectName, false, 256) {
   
            @NotNull
            @Override
            public List<FieldError> getFieldErrors() {
   
                return fieldErrors;
            }
        };
    }
}

// 调用方法
ValidationUtil.validate(paramValue, "param name");

相关推荐

  1. SpringMVC校验注解生效

    2024-02-01 14:06:01       34 阅读
  2. jsonfield注解生效

    2024-02-01 14:06:01       18 阅读
  3. SpringMVC常用注解

    2024-02-01 14:06:01       25 阅读
  4. SpringMVC常用注解

    2024-02-01 14:06:01       37 阅读
  5. SpringMVC-注解版本

    2024-02-01 14:06:01       37 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-01 14:06:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-01 14:06:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-01 14:06:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-01 14:06:01       20 阅读

热门阅读

  1. C++的学习记录

    2024-02-01 14:06:01       37 阅读
  2. 【Midjourney】新手指南:参数设置

    2024-02-01 14:06:01       29 阅读
  3. 【数据结构】单调队列

    2024-02-01 14:06:01       37 阅读
  4. C语言结构体

    2024-02-01 14:06:01       34 阅读
  5. 图论——最短路径

    2024-02-01 14:06:01       24 阅读
  6. JUnit

    JUnit

    2024-02-01 14:06:01      32 阅读
  7. vue登陆修改密码等加密(禁止明文传输)

    2024-02-01 14:06:01       28 阅读
  8. Python 将文本转换成语音播放 pyttsx3

    2024-02-01 14:06:01       25 阅读
  9. 【GPU驱动开发】- GPU架构流程

    2024-02-01 14:06:01       25 阅读
  10. go语言-字符串处理常用函数

    2024-02-01 14:06:01       26 阅读
  11. P3654 First Step (ファーストステップ)题解

    2024-02-01 14:06:01       34 阅读
  12. 你保存alzet渗透泵中文说明书了吗?

    2024-02-01 14:06:01       31 阅读