Я использовал джерси для создания веб-сервисов. Я создал фильтр запросов, используя ContainerRequestFilter. Я прошел через Фильтр запросов Джерси только по определенному вопросу URI, но Я хочу исключить фильтр только для некоторых URL.

@Provider
public class AuthFilter implements ContainerRequestFilter{

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

// business logic

   }
}
16
curiousmind 5 Сен 2016 в 13:46

3 ответа

Лучший ответ

Фильтры привязки имен

Вместо исключения URI из глобального фильтра вы можете рассмотреть возможность использования фильтра привязки имени для выбора конечных точек, к которым будет привязан ваш фильтр.

Также проверьте этот ответ для некоторых примеров с фильтрами привязки имен.

Глобальные фильтры

Если вас по-прежнему устраивает подход с использованием глобального фильтра, вы можете рассмотреть возможность использования UriInfo, чтобы получить подробную информацию о запрошенном URI. Используйте один из следующих подходов, чтобы получить экземпляр UriInfo:

  1. Использование @Context аннотация:

    @Provider
    public class AuthFilter implements ContainerRequestFilter {
    
        @Context
        private UriInfo info;
    
        @Override
        public void filter(ContainerRequestContext requestContext) throws IOException {
            ...
        }
    }
    
  1. Получение его из ContainerRequestContext < / а>:

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        UriInfo info = requestContext.getUriInfo();
        ...
    }
    

Когда у вас будет экземпляр UriInfo, у вас будет доступ к ряду методов, которые могут быть полезны:

Для получения дополнительных сведений см. {{X0} } документации.

Если запрошенный URI не соответствует URI, к которому вы хотите применить фильтр, просто используйте инструкцию return:

@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
    UriInfo info = requestContext.getUriInfo();
    if (!info.getPath().contains("secured")) {
        return;
    }
}

Динамическое связывание…

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

Следующий пример извлечен из документации Джерси. показывает, как реализовать динамическое связывание:

@Path("helloworld")
public class HelloWorldResource {

    @GET
    @Produces("text/plain")
    public String getHello() {
        return "Hello World!";
    }

    @GET
    @Path("too-much-data")
    public String getVeryLongString() {
        String str = ... // very long string
        return str;
    }
}
// This dynamic binding provider registers GZIPWriterInterceptor
// only for HelloWorldResource and methods that contain
// "VeryLongString" in their name. It will be executed during
// application initialization phase.
public class CompressionDynamicBinding implements DynamicFeature {

    @Override
    public void configure(ResourceInfo resourceInfo, FeatureContext context) {
        if (HelloWorldResource.class.equals(resourceInfo.getResourceClass())
                && resourceInfo.getResourceMethod().getName().contains("VeryLongString")) {
            context.register(GZIPWriterInterceptor.class);
        }
    }
}

Привязка выполняется с помощью поставщика, который реализует DynamicFeature интерфейс. Интерфейс определяет один метод configure с двумя аргументами, ResourceInfo и FeatureContext.

ResourceInfo содержит информация о ресурсе и методе, к которому может быть произведена привязка. Метод конфигурации будет выполняться один раз для каждого метода ресурсов, определенного в приложении. В приведенном выше примере провайдер будет выполнен дважды: один раз для метода getHello() и один раз для getVeryLongString() (один раз resourceInfo будет содержать информацию о методе getHello() и один раз он будет укажите на getVeryLongString()).

Если поставщик динамической привязки хочет зарегистрировать любого поставщика для фактического метода ресурсов, он сделает это, используя предоставленный FeatureContext, расширяющий конфигурируемый API JAX-RS. Могут использоваться все методы регистрации классов или экземпляров фильтров или перехватчиков. Такие динамически регистрируемые фильтры или перехватчики будут привязаны только к фактическому методу ресурса. В приведенном выше примере GZIPWriterInterceptor будет привязан только к методу getVeryLongString(), что вызовет сжатие данных только для этого метода, а не для метода getHello().

Обратите внимание, что фильтры и перехватчики, зарегистрированные с использованием динамической привязки, являются только дополнительными фильтрами, выполняемыми для метода ресурса. Если есть какие-либо поставщики с привязкой к имени или глобальные поставщики, они все равно будут выполняться.


Дополнительные сведения см. В документации Джерси. про фильтры и перехватчики.

29
svarog 19 Янв 2020 в 13:06

Вероятно, вы можете проверить шаблон URL и прервать запрос, используя getUri

Что-то вроде следующего

public class AuthFilter implements ContainerRequestFilter{

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

       String path =    requestContext.getUriInfo().getPath();
       if(path.contains("admin")){
          requestContext.abortWith(new Response());
       }

   }
}

https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/filters-and-interceptors.html#d0e9339

-1
svarog 19 Янв 2020 в 13:19

Использование @NameBinding может быть наиболее элегантным подходом, но если вы просто хотите исключить один ресурс и применить фильтр ко всем остальным, вы должны не забыть поместить аннотацию привязки ко всем ресурсам. В этом случае вы можете использовать ContainerRequestContext.getUriInfo().getMatchedResources(), чтобы проверить соответствие целевого ресурса. Это лучше, чем жестко запрограммировать путь, который может измениться.

В приведенном ниже примере будет применяться логика фильтра ко всем ресурсам, кроме StatusResource:

public class CorsContainerRequestFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext req) {
        if (!matchesStatusResource(req)) {
            // filter logic
        }
    }

    private boolean matchesStatusResource(ContainerRequestContext req) {
        List<Object> matchedResources = req.getUriInfo().getMatchedResources();
        for (Object matchedResource : matchedResources) {
            if (matchedResource instanceof StatusResource) {
                return true;
            }
        }
        return false;
    }
}

Как упоминалось другими, вместо этого можно использовать динамические привязки, но это довольно уродливо, поскольку не очевидно, что фильтр не будет применяться ко всем ресурсам.

3
Jonathan 26 Июл 2017 в 15:53