JacksonPropertyNodeNameProvider не выбирает правильное значение, когда свойство добавляется в пользовательскую созданную зависимость - PullRequest
0 голосов
/ 23 марта 2020

Я использую JacksonPropertyNodeNameProvider для визуализации ошибки с фактическим json именем поля вместо java имени поля класса, т.е. account_id вместо accountId. Я добавил пользовательское ограничение, поскольку я хочу проверять несколько полей. Когда я добавляю пользовательскую ошибку

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

, она просто возвращает customField в ошибке вместо поля custom_. Если я пытаюсь установить 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();
}

1 Ответ

0 голосов
/ 23 марта 2020

Единственный способ, с которым я пришел сейчас, - это вручную получить fieldNames перед возвратом ответа. Это хакерское решение, но не смог найти другой подход. Причина в том, что org.springframework.validation.beanvalidation.SpringValidatorAdapter#getRejectedValue использует getPropertyAccessor().getPropertyValue(field) для получения отклоненного значения, и для его работы требуется точное имя поля.

@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;
    }
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...