JacksonPropertyNodeNameProvider未选择正确的值,当在定制的Created Constraint中添加属性时

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

我正在使用JacksonPropertyNodeNameProvider使用实际的json字段名称而不是Java类字段名称来呈现错误,即account_id而不是accountId。我想在多个字段上进行验证时添加了一个自定义约束。当我添加自定义错误时

context.buildConstraintViolationWithTemplate("customField is a mandatory unique attribute")
            .addPropertyNode("customField").addBeanNode().addConstraintViolation();

它只在错误而不是custom_field中返回customField。如果我尝试将PropertNode设置为custom_field,则会出现ISE错误。是否需要设置某些配置或需要执行其他操作才能使此工作正常进行?这就是初始化验证器的方式。

@Bean
public Validator validator(@Autowired ObjectMapper objectMapper) {
    JacksonPropertyNodeNameProvider propertyNodeNameProvider = new JacksonPropertyNodeNameProvider(objectMapper);
    ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
            .configure()
            .propertyNodeNameProvider(propertyNodeNameProvider)
            .buildValidatorFactory();
    return validatorFactory.getValidator();
}
java spring spring-boot hibernate-validator
1个回答
0
投票

我现在想出的唯一方法是在返回响应之前手动检索fieldNames。这是一个骇人听闻的解决方案,但找不到其他方法。原因是org.springframework.validation.beanvalidation.SpringValidatorAdapter#getRejectedValue使用getPropertyAccessor().getPropertyValue(field)来获取拒绝的值,并且它必须具有确切的fieldName才能起作用。

@ControllerAdvice
public class RestControllerExceptionHandler
    extends ResponseEntityExceptionHandler {
@Autowired
PropertyNodeNameProvider provider;

@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
        MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
    ErrorResponse errorResponse = new ErrorResponse(INVALID_INPUT.getType(), INVALID_INPUT.getMessage())
    ex.getBindingResult().getAllErrors().forEach(e -> {
        if (e instanceof FieldError) {
            FieldError fe = (FieldError) e;
            //Manually find the equivalent json property.
            var cv =  fe.unwrap(ConstraintViolationImpl.class);
            var field_name = provider.getName(new JavaBeanPropertyImpl(cv.getRootBeanClass(), fe.getField()));
            errorResponse.addError(field_name, fe.getDefaultMessage());
        }
    });
    return new ResponseEntity<>(errorResponse, INVALID_INPUT.getStatus());
}


private static class JavaBeanPropertyImpl
        implements JavaBeanProperty {
    private final Class<?> declaringClass;
    private final String name;

    private JavaBeanPropertyImpl(Class<?> declaringClass, String name) {
        this.declaringClass = declaringClass;
        this.name = name;
    }

    @Override
    public Class<?> getDeclaringClass() {
        return declaringClass;
    }

    @Override
    public String getName() {
        return name;
    }
}

}

© www.soinside.com 2019 - 2024. All rights reserved.