Spring 5 PathVariable Validation вызывает Http 404 - PullRequest
0 голосов
/ 15 июня 2019

Когда я добавляю @Validated в Spring RestConstroller, я получаю ответ HTTP 404 для конечных точек этого контроллера. Перед добавлением аннотации конечная точка найдена без проблем.

Проблема связана только с @PathVariable, и у меня корректная работа проверки (с использованием @Valid) с не примитивными параметрами RequestBody.

Есть довольно много статей по этому вопросу, и я потратил значительное количество времени, пытаясь несколько вариантов без успеха. Самое простое это.

Согласно этому простому примеру https://sdqali.in/blog/2015/12/05/validating-requestparams-and-pathvariables-in-spring-mvc/ Я полагаю, что это должно быть так же просто, как добавить @Validated к контроллеру, исключив @Valid для параметра PathVariable и добавив компонент MethodValidationPostProcessor. Предпочтительно я бы использовал @Valid вместо @Validated.

Я использую Spring 5 (не загрузочный) и у меня есть hibernate-validator 6.0.16.Final на пути к классам

Проблемный RestController

@Validated
@RestController
@RequestMapping(value = "practices")
public class RestPracticeResource implements PracticeResource {

    @Override
    @GetMapping("/{id}")
    public ResponseEntity<Practice> getPractice(@Id @PathVariable("id") final String id) throws ResourceNotFoundException {
        final UUID uuidId = UUID.fromString(id);
    }
}

Рабочий RestController для RequestBody

@RestController
@RequestMapping(value = "accounts")
public class RestAccountResource implements AccountResource {

    @Override
    @PostMapping
    public ResponseEntity<AccountDto> create(@NotNull @Valid @RequestBody final CreateAccountDto createAccountDto)
            throws ResourceAlreadyExistsException {
        ...
    }
}

Id Аннотация

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

    // ... Stock standard code here

    class IdValidator implements ConstraintValidator<Id, String> {

        @Override
        public void initialize(final Id id) {}

        @Override
        public boolean isValid(final String id, final ConstraintValidatorContext constraintValidatorContext) {
            // Basic REGEX match for UUID format
            return ValidationUtil.isValidId(id);
        }
    }
}

ExceptionHander

@ExceptionHandler(ConstraintViolationException.class)
public final ResponseEntity<ApiError> handleConstraintViolationException(final ConstraintViolationException ex,
                                                                         final WebRequest webRequest) {
    // .. extract violations into standard format
    return new ResponseEntity<>(apiError, BAD_REQUEST);
}

MethodValidationPostProcessor bean

@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
    return new MethodValidationPostProcessor();
}

Фактические результаты

Как только я добавляю @Validated, я получаю ответы Http 404 для конечной точки /practices/{id} независимо от того, какой формат у провайдера I id. Если я удаляю @Validated, я могу передать действительный UUID, и все в порядке, или передать неверный UUID и получить исключение, выданное UUID.fromString(id).

@Id игнорируется, если я пытаюсь использовать @Valid в соответствии с проверкой тела запроса.

Ожидаемые результаты

При добавлении @Validated будет включена проверка аннотации @Id, и выдается ConstraintViolationException, если предоставляется {id} в формате, отличном от UUID.

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