zoukankan      html  css  js  c++  java
  • 版本不匹配引发的坑:javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint

    发现一个API报了错:

    javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.NotEmpty' validating type 'java.lang.String'. Check configuration for 'cancelReason'
        at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.throwExceptionForNullValidator(ConstraintTree.java:229) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
        at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getConstraintValidatorNoUnwrapping(ConstraintTree.java:310) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
        at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getConstraintValidatorInstanceForAutomaticUnwrapping(ConstraintTree.java:244) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
        at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getInitializedConstraintValidator(ConstraintTree.java:163) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
        at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:116) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
        at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:87) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
        at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:73) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:621) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:584) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForSingleDefaultGroupElement(ValidatorImpl.java:528) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:496) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:461) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:411) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
        at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:208) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
        at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:103) ~[spring-context-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        at org.springframework.boot.autoconfigure.web.WebMvcValidator.validate(WebMvcValidator.java:64) ~[spring-boot-autoconfigure-1.5.13.RELEASE.jar:1.5.13.RELEASE]
        at org.springframework.validation.DataBinder.validate(DataBinder.java:895) ~[spring-context-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.validateIfApplicable(AbstractMessageConverterMethodArgumentResolver.java:270) ~[spring-webmvc-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:133) ~[spring-webmvc-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158) ~[spring-web-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) ~[spring-web-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:883) [spring-webmvc-4.3.17.RELEASE.jar:4.3.17.RELEASE]

    一、Spring MVC的参数校验
    Spring的参数校验会用到两个库:validation-api,hibernate-validator
    validation-api是一套标准,hibernate-validator实现了此标准。
    JSR-303 是Java EE 6 中的一项子规范,叫做BeanValidation,官方参考实现是hibernate-validator。

    二、HV000030: No validator
    报这个错,一般有两种情况:
    (1)约束与对象属性不匹配,譬如在String 上使用javax.validation.constraints.Future就会报这个错
    (2)真的是没有相关的Validator

    一下子觉得很奇怪,难道javax.validation.constraints.NotEmpty不能用在java.lang.String??

    这有什么错呢!!

    真的是没有Validator?

    如果有,会是这样的,以javax.validation.constraints.Future为例:

    还真没有!!但是@NotEmpty是有两个的
    看了下线上在跑的的API,发现使用的是org.hibernate.validator.constraints.NotEmpty。
    刚才也看到了,也是没有对应Validator
    但是有一些与javax.validation.constraints.NotEmpty不一样的地方:使用了两个元约束@NotNull和@Size(min=1)
     

    也就是一个校验不需要一个专门的Validator也是可以的?

     
    三、ComposingConstraints【组合约束】

    打断点看了下,hibernate-validator在处理约束时,使用组合约束的概念【可扩展性好强】。
    具体工作流程如下:
    (1)先递归校验组合约束。譬如org.hibernate.validator.constraints.NotEmpty中的@NotNull和@Size(min=1)
    (2)校验主约束,如果有则校验;否则,跳过。譬如org.hibernate.validator.constraints.NotEmpty
    (3)处理组合约束的校验结果。有三种策略:OR,AND,ALL_FALSE
    org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree#validateConstraints(org.hibernate.validator.internal.engine.ValidationContext<T>, org.hibernate.validator.internal.engine.ValueContext<?,V>, java.util.Set<javax.validation.ConstraintViolation<T>>)

    org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree#validateComposingConstraints

    四、为什么会有这个一定会报错的javax.validation.constraints.NotEmpty呢?

    大家都知道Spring Boot帮助我们做了一件脏活、累活【感恩】:依赖包的版本管理。难道此处有bug?
    使用IDEA中的Maven Helper插件看一下:

    Jump to Source,原来是pom.xml中显式引入2.0.1.Final的validator-api

     Spring Boot1.5.13中使用的是1.1.0.Final

    问了下当时添加此依赖的同学,反馈是从老项目中继承过来的,当时是为了解决JPA的一个问题。不过现在已经全部改用Mybatis,那么这个是可以去掉的。
    把项目所有的微服务check了一遍,发现只有这个项目有。
    去掉并回归了下,相关接口并没有受到影响。OK,收工

     补充:
    validation-api,hibernate-validator依赖及匹配的版本:

     

     

    参考:
    https://www.cnblogs.com/softidea/p/5907423.html

  • 相关阅读:
    Android-PullToRefresh 下拉刷新增加setOnItemLongClickListener
    【453】周志华-机器学习-读书笔记
    【452】pandas筛选出表中满足另一个表所有条件的数据
    【451】python 同一行打印进度条
    【449】Win10 蓝牙耳机链接没有声音
    HBase(一)HBase入门简介
    kafka可视化客户端工具(Kafka Tool)的基本使用
    Kafka(五)Kafka的API操作和拦截器
    Kafka(四)Kafka在zookeeper中的存储
    Kafka(三)Kafka的高可用与生产消费过程解析
  • 原文地址:https://www.cnblogs.com/softidea/p/12183236.html
Copyright © 2011-2022 走看看