javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 解决方法

在使用hibernate validator进行参数有效性校验的时候,我们有时候会遇到javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint ,比如,在我们的应用中,使用了自定义注解Dict对枚举进行有效性校验,因为定义的Dict应用于String类型,例如:

package com.yidoo.base.metadata.validate;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

@Target({ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
@Constraint(validatedBy = { DictValidator.class })
@Documented
public @interface Dict {
    /**
     * 数据字典的标准名称, 驼峰式或者下划线分隔都可以
     * @return
     */
    String dictName();

    /**
     * 表示验证数据字典有效性的范围为明确指定的字段名。<br />
     * 用于一些特殊场景, 比如订单状态中有作废, 但是这些有效性我们不希望业务订单明确传递这个值, <br />
     * 所以要过滤掉, 适用于重用数据字典, 但是取值范围为子集的情况。
     * 默认为空,表示所有子项目都有效。相当于除非声明某些有效,否则全部有效。
     * @return
     */
    String fieldName() default "";

    String message() default "{数据字典取值不合法,请参考标准数据字典管理}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}
package com.yidoo.base.metadata.validate;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import com.yidoo.base.metadata.cons.DictUtils;

public class DictValidator implements ConstraintValidator<Dict, String> {

    private String dictName;

    @Override
    public void initialize(Dict dictAnno) {
        this.dictName = dictAnno.dictName();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (DictUtils.isValid(dictName, value)) {
            return true;
        }
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate("该字段的当前值" + value + "不在数据字典" + dictName + "的有效取值范围内, 有效值为:[" + DictUtils.getDictKeys(dictName) + "]").addConstraintViolation();
        return false;
    }

}

在如下校验中就会失败:

    @NotNull
    @ValidServices(services = IOperatorService.SAVE)
    @Dict(dictName="bool_int")
    private Integer loginFlag;

如下:

javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint ‘com.yidoo.base.metadata.validate.Dict‘ validating type ‘java.lang.Integer‘. Check configuration for ‘firstTimeFlag‘
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.throwExceptionForNullValidator(ConstraintTree.java:228)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getConstraintValidatorNoUnwrapping(ConstraintTree.java:309)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getConstraintValidatorInstanceForAutomaticUnwrapping(ConstraintTree.java:243)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getInitializedConstraintValidator(ConstraintTree.java:164)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:109)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:88)
    at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:73)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:617)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:582)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validatePropertyForSingleDefaultGroupElement(ValidatorImpl.java:1051)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validatePropertyForDefaultGroup(ValidatorImpl.java:1019)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validatePropertyForCurrentGroup(ValidatorImpl.java:936)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validatePropertyInContext(ValidatorImpl.java:824)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateProperty(ValidatorImpl.java:223)
    at com.yidoo.utils.ValidationUtils.validatePropertyInternal(ValidationUtils.java:56)
    at com.yidoo.utils.ValidationUtils.validateEntityByServiceId(ValidationUtils.java:99)
    at com.yidoo.utils.LfValidUtil.newValid(LfValidUtil.java:37)
    at com.yidoo.k3c.base.service.ClientService.insert(ClientService.java:129)

当遇到有些设计,取值为布尔类型,0代表false,1代表true的时候,采用了Integer类型,使用Dict注解的时候就会出现上述错误,对于该异常,原因是Dict的校验器参数String不匹配Integer,要解决该异常,我们可以再定义一个针对Integer有效性校验的IntDict,如下所示:

package com.yidoo.base.metadata.validate;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

@Target({ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
@Constraint(validatedBy = { IntDictValidator.class })
@Documented
public @interface IntDict {
    /**
     * 数据字典的标准名称, 驼峰式或者下划线分隔都可以
     * @return
     */
    String dictName();

    /**
     * 表示验证数据字典有效性的范围为明确指定的字段名。<br />
     * 用于一些特殊场景, 比如订单状态中有作废, 但是这些有效性我们不希望业务订单明确传递这个值, <br />
     * 所以要过滤掉, 适用于重用数据字典, 但是取值范围为子集的情况。
     * 默认为空,表示所有子项目都有效。相当于除非声明某些有效,否则全部有效。
     * @return
     */
    String fieldName() default "";

    String message() default "{数据字典取值不合法,请参考标准数据字典管理}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}
package com.yidoo.base.metadata.validate;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import com.yidoo.base.metadata.cons.DictUtils;

public class IntDictValidator implements ConstraintValidator<IntDict, Integer> {

    private String dictName;

    @Override
    public void initialize(IntDict dictAnno) {
        this.dictName = dictAnno.dictName();
    }

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        if (DictUtils.isValid(dictName, String.valueOf(value))) {
            return true;
        }
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate("该字段的当前值" + value + "不在数据字典" + dictName + "的有效取值范围内, 有效值为:[" + DictUtils.getDictKeys(dictName) + "]").addConstraintViolation();
        return false;
    }

}

注:为什么不直接采用正则校验呢?因为对于很多枚举类型来说,取值范围是业务随机定义的,此时可能依赖于常量、枚举类甚至动态加载到缓存的定义进行校验(看不同系统的设计约定和规范)。

原文地址:https://www.cnblogs.com/zhjh256/p/9160473.html

时间: 2024-10-28 20:07:55

javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 解决方法的相关文章

javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint

使用hibernate validator出现上面的错误, 需要 注意 @NotNull 和 @NotEmpty  和@NotBlank 区别 @NotEmpty 用在集合类上面@NotBlank 用在String上面@NotNull    用在基本类型上 如果在基本类型上面用NotEmpty或者NotBlank 会出现上面的错 http://blog.csdn.net/dracotianlong/article/details/23181729 javax.validation.Unexpec

javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint,NotBlank判断不能为空

java 验证出现如下错误: javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint错误原因      Java实体类中属性是Integer类型,用了NotBlank判断不能为空,而这个注解是判断字符串是否为空 3.解决办法 去掉@NotBlank注解.使用@NotNull————————————————版权声明:本文为CSDN博主「无名_四叶草」的原创文章,遵循

版本不匹配引发的血案: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.i

javax.validation.UnexpectedTypeException: No validator could be found for type: java.lang.Integer

[java] view plaincopyprint? Apr 8, 2014 2:13:57 PM org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet springmvc threw exception javax.validation.UnexpectedTypeException: No validator could be found for type: ja

spring boot中使用javax.validation以及org.hibernate.validator校验入参

这里springboot用的版本是:<version>2.1.1.RELEASE</version> 自带了hibernate.validator,所以不用添加额外依赖 1.创建个对应前台form的测试vo,并添加字段校验注解 import java.math.BigDecimal; import java.util.Date; import java.util.List; import javax.validation.constraints.AssertTrue; import

javax.servlet.ServletException cannot be resolved to a type错误解决方法

在页面中使用全局路径时${pageContext.request.contextPath}出现javax.servlet.ServletException cannot be resolved to a type错误,解决方法如下: 这个错误主要是因为缺少jsp-api.jar 和  servlet-api.jar这两个Jar包. 第一种解决方法: 直接把 Tomcat7.0 下lib目录中的 jsp-api.jar 添加  Build path 中. 第二种解决方法:使用 Maven 将 js

Spring Validation(使用Hibernate Validator)

1.需要的jar包 hibernate-validator.5.1.3.Final.jar validation-api.1.1.0.Final.jar 2.springsevlet-config.xml配置 在spring3之后,任何支持JSR303的validator(如Hibernate Validator)都可以通过简单配置引入,只需要在配置xml中加入,这时validatemessage的属性文件默认为classpath下的ValidationMessages.properties:

[javax.validation]验证

package main; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import javax.validation.constraints.Max; import javax.va

javax.validation.ValidationException: Unable to create a Configuration, because no Bean Validation provider could be found

1 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.validation.beanvalidation.LocalValidatorFactoryBean#0': Invocation of init method failed; nested exception is javax.validation.ValidationExc