错误“约束为 java.util.UUID 类型定义了多个验证程序”,尽管只使用了单个验证程序

Error 'Constraint defines multiple validators for the type java.util.UUID", despite using only a single validator

提问人:Wired5149 提问时间:9/6/2023 更新时间:9/6/2023 访问量:41

问:

在调查我们项目中的错误时,我发现了一个奇怪的 Spring 错误,或者至少是一个奇怪的行为。在运行时,每当有人调用一个特定的端点时,他们都会返回错误 500,原因是:

“ExistsSomeEntity 为 java.util.UUID 类型定义了多个验证器:com.example.validation.ExistsSomeEntityValidator、com.example.validation.ExistsSomeEntityValidator。只允许一个

终结点调用的方法的代码如下:

public void doSomethingWithAnEntity(@ExistsSomeEntity UUID id, WhatToDoRequest request) {
doSomething(id,request);
    }

验证:

@Constraint(validatedBy = ExistsSomeEntityValidator.class)
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExistsSomeEntity {

    String message() default "{error.validation.ExistsSomeEntity.message}";

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

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

验证者:

public class ExistsSomeEntityValidator implements ConstraintValidator<ExistsSomeEntity, UUID> {

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    private someDAO SomeEntityDAO;


    @Override
    public boolean isValid(UUID id, ConstraintValidatorContext constraintValidatorContext) {
        checkForEntity(id, someDAO);
    }
}

正如你所看到的,只定义了一个验证者,它似乎没有任何明显的问题。这段代码使用了大约半年,没有触发这个错误......

在多次尝试寻找原因后,我注意到验证注释只用于参数,从不用于字段,所以我修改了它,如下所示:

验证:

@Constraint(validatedBy = ExistsSomeEntityValidator.class)
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExistsSomeEntity {

    String message() default "{error.validation.ExistsSomeEntity.message}";

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

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

验证者:

@RequiredArgsConstructor
public class ExistsSomeEntityValidator implements ConstraintValidator<ExistsSomeEntity, UUID> {

    private final someDAO SomeEntityDAO;

    @Override
    public boolean isValid(UUID id, ConstraintValidatorContext constraintValidatorContext) {
        checkForEntity(id, someDAO);
    }
}

摆脱@Autowired并使用龙目岛似乎已经解决了这个问题,因为验证现在按预期工作,但我找不到任何原因,为什么它会这样。我无法想象不使用 Lombok 的人会被阻止在 Spring 中使用注释验证器。有什么想法吗?

Java Spring 验证 注释 龙目岛

评论


答: 暂无答案