Джерси Запрос Фильтровать только по определенному URI

Я пытаюсь выполнить некоторую проверку на запросы, входящие в мою службу, с помощью ContainerRequestFilter. Все работает нормально, однако есть одна проблема: каждый запрос проходит через фильтры, хотя некоторые из них никогда не будут применяться к ним (один фильтр проверяет только на ResourceOne, другой только на ResourceTwo и т.д.)

Можно ли установить фильтр только для запроса при определенных условиях?

Хотя это не блокиратор или препятствие, было бы неплохо иметь возможность остановить такое поведение:)

Ответы

Ответ 1

Я предполагаю, что вы используете Jersey 2.x(реализация для API JAX-RS 2.0).

У вас есть два способа достижения своей цели.

1. Использовать привязки имен:


1.1. Создание пользовательской аннотации, аннотированной с помощью @NameBinding:

@NameBinding
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationForResourceOne {}

1,2. Создайте фильтр с помощью аннотации:

@Provider
@PreMatching
@AnnotationForResourceOne
public class ResourceOneFilter implements ContainerRequestFilter {
...
}

1,3. И связать созданный фильтр с выбранным методом ресурса:

@Path("/resources")
public class Resources {
    @GET
    @Path("/resourceOne")
    @AnnotationForResourceOne
    public String getResourceOne() {...}
}

2. Используйте DynamicFeature:


2,1. Создать фильтр:

public class ResourceOneFilter implements ContainerRequestFilter {
...
}

2,2. Реализовать интерфейс javax.ws.rs.container.DynamicFeature:

@Provider
public class MaxAgeFeature implements DynamicFeature {
    public void configure(ResourceInfo ri, FeatureContext ctx) {
        if(resourceShouldBeFiltered(ri)){
            ResourceOneFilter filter = new ResourceOneFilter();
            ctx.register(filter);
        }
    }
}

В этом случае:

  • фильтр не аннотируется аннотацией @Provider;
  • configure(...) метод вызывается для каждого метода ресурсов;
  • ctx.register(filter) связывает фильтр с методом ресурсов;

Ответ 2

Когда мы используем @NameBinding, нам нужно удалить аннотацию @PreMatching из фильтра. @PreMatching вызывает все запросы, проходящие через фильтр.

Ответ 3

@PreMatching не работает вместе с @NameBinding, потому что класс ресурсов/метод еще не известен в фазе предварительного согласования. Я решил эту проблему, удалив @PreMatching из фильтра и используя приоритет привязки. См. ResourceConfig.register(Object component, int bindingPriority).

Фильтры, которые должны быть выполнены до того, как ресурс просто получит более высокий приоритет.