简体   繁体   English

Java:自定义枚举验证器注释未在 Spring RestControllerAdvice 异常处理程序中触发

[英]Java: custom enum validator annotation not triggered in Spring RestControllerAdvice exception handler

A custom enum validator annotation interface:自定义枚举验证器注释接口:

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = PanTypeSubSetValidator.class)
public @interface PanTypeSubset {
    PanType[] anyOf();
    String message() default "must be any of {anyOf}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

and the actual implementation:和实际实现:

public class PanTypeSubSetValidator implements ConstraintValidator<PanTypeSubset, PanType> {
    private PanType[] subset;

    @Override
    public void initialize(PanTypeSubset constraint) {
        this.subset = constraint.anyOf();
    }

    @Override
    public boolean isValid(PanType value, ConstraintValidatorContext context) {
        return value == null || Arrays.asList(subset).contains(value);
    }
}

and the usage inside a request DTO:以及请求 DTO 中的用法:

@SuperBuilder
@Data
@NoArgsConstructor
public class PanBaseRequestDto {

    @NotNull(message = "'PANTYPE' cannot be empty or null")
    @PanTypeSubset(anyOf = {PanType.PAN, PanType.TOKEN}, message = "yesssss")
    private PanType panType;

}

The problem is that this annotation never seems to be triggered.问题是这个注释似乎永远不会被触发。 I get another exception kick in in the @RestControllerAdvice DefaultExceptionHandler implementation before this actual validation:在实际验证之前,我在 @RestControllerAdvice DefaultExceptionHandler 实现中遇到了另一个异常:

Handling generic exception: (Invalid JSON input: Cannot deserialize value of type `...pantoken.PanType` from String "PAN1": not one of the values accepted for Enum class: [TOKEN, PAN]; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `...pantoken.PanType` from String "PAN1": not one of the values accepted for Enum class: [TOKEN, PAN]

Solved it by creating a custom @JsonCreator function inside the ENUM class.通过在ENUM类中创建自定义@JsonCreator函数来解决它。 Not the best approach, as we loose the value that user has submitted when displaying error to the end client, but it's ok for me.不是最好的方法,因为我们在向最终客户端显示错误时丢失了用户提交的值,但对我来说没问题。

@JsonCreator
public static PanType create(String value) {
    if (Objects.isNull(value)) {
        return null;
    }

    return Arrays.stream(PanType.values())
            .filter(v -> value.equals(v.getType()))
            .findFirst()
            .orElse(PanType.UNKNOWN);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM