Я использовал джерси для создания веб-сервисов. Я создал фильтр запросов, используя ContainerRequestFilter
. Я прошел через Фильтр запросов Джерси только по определенному вопросу URI, но Я хочу исключить фильтр только для некоторых URL.
@Provider
public class AuthFilter implements ContainerRequestFilter{
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
// business logic
}
}
3 ответа
Фильтры привязки имен
Вместо исключения URI из глобального фильтра вы можете рассмотреть возможность использования фильтра привязки имени для выбора конечных точек, к которым будет привязан ваш фильтр.
Также проверьте этот ответ для некоторых примеров с фильтрами привязки имен.
Глобальные фильтры
Если вас по-прежнему устраивает подход с использованием глобального фильтра, вы можете рассмотреть возможность использования UriInfo
, чтобы получить подробную информацию о запрошенном URI. Используйте один из следующих подходов, чтобы получить экземпляр UriInfo
:
Использование
@Context
аннотация:@Provider public class AuthFilter implements ContainerRequestFilter { @Context private UriInfo info; @Override public void filter(ContainerRequestContext requestContext) throws IOException { ... } }
Получение его из
ContainerRequestContext
< / а>:@Override public void filter(ContainerRequestContext requestContext) throws IOException { UriInfo info = requestContext.getUriInfo(); ... }
Когда у вас будет экземпляр UriInfo
, у вас будет доступ к ряду методов, которые могут быть полезны:
getAbsolutePath()
< / a>: получить абсолютный путь запроса.-
getBaseUri()
< / a>: получить базовый URI приложения. -
getMatchedResources()
< / a>: получить доступный только для чтения список экземпляров класса ресурсов, совпадающих в данный момент. -
getMatchedURIs()
< / a>: получить доступный только для чтения список URI для сопоставленных ресурсов. -
getPath()
< / a>: получить путь к текущему запросу относительно базового URI в виде строки. -
getPathSegments()
< / a>: получить путь к текущему запросу относительно базового URI в виде списка изPathSegment
. getRequestUri()
< / a>: получить абсолютный URI запроса, включая любые параметры запроса.- { {X0}}: преобразовать URI в соответствие с текущим URI запроса.
- { {X0}}: разрешить относительный URI по отношению к базовому URI приложения.
Для получения дополнительных сведений см. {{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()
.
Обратите внимание, что фильтры и перехватчики, зарегистрированные с использованием динамической привязки, являются только дополнительными фильтрами, выполняемыми для метода ресурса. Если есть какие-либо поставщики с привязкой к имени или глобальные поставщики, они все равно будут выполняться.
Дополнительные сведения см. В документации Джерси. про фильтры и перехватчики.
Вероятно, вы можете проверить шаблон 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());
}
}
}
Использование @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;
}
}
Как упоминалось другими, вместо этого можно использовать динамические привязки, но это довольно уродливо, поскольку не очевидно, что фильтр не будет применяться ко всем ресурсам.
Похожие вопросы
Связанные вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.