Spring框架中的Jackson反序列化错误处理

问题描述 投票:0回答:1

我正在寻找一种干净的方法来处理REST Web请求的杰克逊反序列化错误。

更确切地说:我在传入的DTO对象中有一个枚举,从JSON映射。但是如果用户发送了错误的值,则返回400 Bad Request。我想用正确的信息返回422 Unprocessable Entity

一种选择是接受String,并使用bean验证。但是,不可能将所有枚举值作为列表传递给注释(而不是常量),因此我需要单独传递所有枚举值并使它们保持最新。这在整个应用程序中非常容易出错。我正在寻找一种更具结构性的方法来处理这个问题。

spring error-handling enums jackson json-deserialization
1个回答
2
投票

我通过在DTO中使用String并使用public @interface EnumValueas注释解决了这个问题。

Enum值:

@ReportAsSingleViolation
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumValueValidator.class)
@Target(ElementType.FIELD)
public @interface EnumValue {
    Class<? extends Enum> value();
    String message() default "The input contains validation errors.";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
}

验证者:

public class EnumValueValidator implements ConstraintValidator<EnumValue, String> {

    private Class<? extends Enum> enumClass;
    private String message;

    @Override
    public void initialize(final EnumValue constraintAnnotation) {
        this.enumClass = constraintAnnotation.value();
        this.message = constraintAnnotation.message();
    }

    @Override
    public boolean isValid(final String value, final ConstraintValidatorContext context) {
        boolean valid = false;
        for (final Enum enumValue : enumClass.getEnumConstants()) {
            if (enumValue.name().equals(value)) {
                valid = true;
            }
        }
        if (!valid) {
            context.buildConstraintViolationWithTemplate(message) //
                   .addConstraintViolation();
        }
        return valid;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.