Перехват для определенного пути с параметром пути в JAX-RS

#jax-rs #interceptor

#jax-rs #перехватчик

Вопрос:

В моем REST api у меня есть ресурс с несколькими вложенными ресурсами. Могу ли я каким-либо образом перехватить любой вызов этого ресурса, а затем продолжить выполнение в обычном режиме?

Например:

 /some-resource/{resource-id}
  

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

 /some-resource/{resource-id}/sub-resource1/...
/some-resource/{resource-id}/sub-resource2/...
...
  

Эти подресурсы имеют сложную структуру с поставщиками во многих разных классах.

Итак, есть ли какой-либо способ перехватывать каждый вызов ресурса, который начинается с пути /some-resource/{resource-id} ? Под перехватом я подразумеваю вызов метода с идентификатором ресурса в качестве параметра, который вызывается перед любой из реализаций вспомогательных ресурсов и может отменить запрос, вызвав исключение, но в остальном не мешает нормальному выполнению.

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

Есть еще идеи?

Ответ №1:

Для этого вы можете использовать RequestFilter:

 @Provider
public class SomeResourceFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        if (isSubresourceOfSomeResource(requestContext)) {
            intercept(resourceId(requestContext));
        }
    }

    private boolean isSubresourceOfSomeResource(ContainerRequestContext requestContext) {
        List<PathSegment> pathSegments = requestContext.getUriInfo().getPathSegments();
        return "some-resource".equals(getSegment(requestContext, 0)) amp;amp; pathSegments.size() > 2;
    }

    private String resourceId(ContainerRequestContext requestContext) {
        return getSegment(requestContext, 1);
    }

    private String getSegment(ContainerRequestContext requestContext, int index) {
        return requestContext.getUriInfo().getPathSegments().get(index).getPath();
    }

    private void intercept(String resourceId) {
        // your code
    }
}