Проверьте URL-путь для нескольких методов контроллера - PullRequest
0 голосов
/ 29 мая 2018

При наличии нескольких ресурсов REST для сбора информации о заказе.

  • /order/{id}
  • /order/{id}/positions
  • /order/{id}/invoice
  • /order/{id}/shipment

В приложении Srping Boot 2 оно реализовано на нескольких контроллерах, например OrderController, InvoiceController и т. Д.

В настоящее время каждый контроллер использует репозиторий OrderRepository для обеспеченияордер с данным id существует.В противном случае это вызывает исключение.Это всегда один и тот же реплицируемый код.

@RestController
public class OrderController {
    // ...
    @GetMapping("order/{id}")
    public Order getCustomer(@PathVariable final Integer id) {
        return this.orderRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("order not found"));
    }
}

Предоставляет ли фреймворк обратный вызов, чтобы записать проверку id только один раз?


Я нашел AntPathMatcher но, похоже, это не правильный путь, поскольку он предоставляет только логический интерфейс.

1 Ответ

0 голосов
/ 29 мая 2018

Обычно это хороший случай для проверки бина .Хотя для многих случаев проверки уже есть встроенная поддержка (@Size, @NotNull, ...), вы также можете написать свои собственные пользовательские ограничения.

Прежде всего, вам нужно определить аннотациючтобы подтвердить свой идентификатор, например:

@Documented
@Constraint(validatedBy = OrderIdValidator.class)
@Target({PARAMETER})
@Retention(RUNTIME)
public @interface ValidOrderId {
    String message() default "Invalid order ID";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

Поскольку ваш идентификатор заказа всегда является параметром для сопоставлений вашего контроллера, вы можете использовать ElementType.PARAMETER, чтобы разрешить аннотацию только для параметров метода.

Следующим шагом является добавление к ней аннотации @Constraint и указание на пользовательский класс валидатора (например, OrderIdValidator):

@Component
public class OrderIdValidator implements ConstraintValidator<ValidOrderId, Integer> {
    private OrderRepository repository;

    public OrderIdValidator(OrderRepository repository) {
        this.repository = repository;
    }

    @Override
    public boolean isValid(Integer id, ConstraintValidatorContext constraintValidatorContext) {
        return repository.existsById(id);
    }
}

Реализуя метод isValid, вы можете проверить,или нет порядок существует.Если он не существует, будет выдано исключение, и в качестве сообщения будет использовано свойство message() аннотации @ValidOrderId.

Последний шаг - добавить аннотацию @Validated ко всемваших контроллеров и добавьте аннотацию @ValidOrderId ко всем параметрам идентификатора заказа, например:

@Validated // Add this
@RestController
public class OrderController {
    @GetMapping("order/{id}")
    public Order getCustomer(@PathVariable @ValidOrderId final Integer id) { // Add @ValidOrderId
        // Do stuff
    }
}

Если вы предпочитаете использовать другой статус ответа для ваших проверок, вы всегда можете добавитькласс, помеченный аннотацией @ControllerAdvice и использующий следующий метод:

@ExceptionHandler(ConstraintViolationException.class)
public void handleConstraints(HttpServletResponse response) throws IOException {
    response.sendError(HttpStatus.BAD_REQUEST.value());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...