解决No validator could be found for constraint ‘javax.validation.constraints.NotBlank‘ validating type

1. 复现问题

今天在使用Knife4j调用后端接口,报出如下错误:

在这里插入图片描述

javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.NotBlank' validating type 'java.lang.Long'. Check configuration for 'id'
	at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getExceptionForNullValidator(ConstraintTree.java:116)
	at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getInitializedConstraintValidator(ConstraintTree.java:162)
	at org.hibernate.validator.internal.engine.constraintvalidation.SimpleConstraintTree.validateConstraints(SimpleConstraintTree.java:54)
	at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:75)
	at org.hibernate.validator.internal.metadata.core.MetaConstraint.doValidateConstraint(MetaConstraint.java:130)
	at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:123)
	at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:555)
	at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForSingleDefaultGroupElement(ValidatorImpl.java:518)
	at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:488)
	at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:450)
	at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:400)
	at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:172)
	at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:109)
	at org.springframework.boot.autoconfigure.validation.ValidatorAdapter.validate(ValidatorAdapter.java:65)
	at org.springframework.validation.DataBinder.validate(DataBinder.java:895)
	at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.validateIfApplicable(AbstractMessageConverterMethodArgumentResolver.java:245)
	at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:137)
	at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
	at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
	......

javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.NotBlank' validating type 'java.lang.Long'. Check configuration for 'id'

2. 分析问题

正赶上最近ChatGPT很火,于是借助ChatGPT来解决我的问题,如下所示:

在这里插入图片描述

This means that the constraint “NotBlank” is not valid for a Long type value in the field “id”. A Long type cannot support the NotBlank constraint. You should either remove the NotBlank annotation or use another type such as a String.

芭比Q的是ChatGPT是英文解释,我们不妨翻译成中文,如下所示:

这意味着约束“NotBlank”对于字段“id”中的长整型类型值无效。Long 类型不能支持 NotBlank 约束。应删除NotBlank注解或使用其他类型(如字符串)。

从中文翻译来看,由于id的类型是长整型的,而NotBlank不能修饰长整型,如下是我的代码:

/** 
 * 自定义组件id 
 * */
@NotBlank(message = "自定义组件id不能为空")
@ApiModelProperty(name = "id", value = "自定义组件id", required = true, example = "1")
private Long id;

但其给出两个解决方案:

  1. 删除NotBlank注解

  2. 使用其他数据类型(如字符串)

显然,这两种方式都无法解决我的问题。

因为id一般都是长整型,因而不能修改其类型,而又不能删除注解,因为必须限制id不能为空。

id不能为空,因而,我们可以考虑不能为空的注解,即@notNull

3. 解决问题

既然@NotBlank注解不能修饰长整型等,而@NotNull注解可以修饰长整型,因而可以进行如下修改:

/**
 * 自定义组件id
 * */
@NotNull(message = "自定义组件id不能为空")
@ApiModelProperty(name = "id", value = "自定义组件id", required = true, example = "1")
private Long id;

重新启动服务后调用接口,即可成功访问,如下图所示:

在这里插入图片描述

此外,@NotBlank注解除了不能修饰长整型,也不能修饰浮点型,布尔型等。

因为@NotBlank注解只能作用在String上,不能为null。而且调用trim()后,长度必须大于0 ("test") ,即必须有实际字符。

4. 重要补充

  1. @NotNull注解

    • 不能为null

    • 可以为empty ,比如""," "

  2. @NotEmpty注解

    • 不能为null

    • 而且长度必须大于0,比如" "

    • 只能使用在字符串上

5. 其他说明

  1. 如果你对Knife4j比较感兴趣,可以参考这篇博文:全网最全的Knife4j swaggerj介绍

  2. 如果你对@NotEmpty、@NotBlank等注解感兴趣,可以参考这篇博文:@NotEmpty、@NotBlank等注解的正确使用

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
非常抱歉,我之前的回答有误。对于Long类型的字段,@Pattern注解不能直接使用,因为它只能验证字符串类型的字段。 如果您需要对Long类型的字段进行正则表达式验证,可以使用自定义验证器来实现。下面是一个示例: 1. 创建一个自定义注解,用于指定需要验证的正则表达式。 ```java @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = LongPatternValidator.class) public @interface LongPattern { String regexp(); String message() default "must match pattern {regexp}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } ``` 2. 创建一个自定义验证器,用于验证Long类型的字段是否符合正则表达式。 ```java public class LongPatternValidator implements ConstraintValidator<LongPattern, Long> { private Pattern pattern; @Override public void initialize(LongPattern constraintAnnotation) { pattern = Pattern.compile(constraintAnnotation.regexp()); } @Override public boolean isValid(Long value, ConstraintValidatorContext context) { if (value == null) { return true; } return pattern.matcher(String.valueOf(value)).matches(); } } ``` 3. 在需要验证的Long类型字段上使用自定义注解@LongPattern。 ```java public class MyRequest { @LongPattern(regexp = "[0-9]{1,19}", message = "id must be a positive integer") private Long id; // getter and setter methods } ``` 在上面的示例中,@LongPattern注解指定了需要验证的正则表达式,LongPatternValidator类实现了对Long类型字段的验证。 希望对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网全栈开发实战

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值