Java Jersey 请求过滤器仅在某些 URI 上
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23641345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jersey Request Filter only on certain URI
提问by KingTravisG
I am trying to do some validation on requests coming into my service using the ContainerRequestFilter
. Everything is working fine, however there is one problem - every single request gets pass through the filters, even though some of the filters will never apply to them (one filter only validates on ResourceOne, another only on ResourceTwo etc.)
我正在尝试使用ContainerRequestFilter
. 一切正常,但是有一个问题 - 每个请求都通过过滤器,即使某些过滤器永远不会应用于它们(一个过滤器仅在 ResourceOne 上验证,另一个仅在 ResourceTwo 上验证等)
Is there a way to set a filter only to be invoked on a request under certain conditions?
有没有办法设置过滤器仅在某些条件下对请求调用?
While it is not a blocker or hindrance, it would be nice to be able to stop this kind of behaviour :)
虽然它不是阻碍或障碍,但能够阻止这种行为会很好:)
采纳答案by pWoz
I assume that You are using Jersey 2.x (implementation for JAX-RS 2.0 API).
我假设您使用的是 Jersey 2.x(JAX-RS 2.0 API 的实现)。
You have two ways to achieve Your goal.
你有两种方法来实现你的目标。
1. Use Name bindings:
1. 使用名称绑定:
1.1 Create custom annotation annotated with @NameBinding:
1.1 创建自定义注解@NameBinding:
@NameBinding
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationForResourceOne {}
1.2. Create filter with Your annotation:
1.2. 使用您的注释创建过滤器:
@Provider
@AnnotationForResourceOne
public class ResourceOneFilter implements ContainerRequestFilter {
...
}
1.3. And bind created filter with selected resource method:
1.3. 并将创建的过滤器与选定的资源方法绑定:
@Path("/resources")
public class Resources {
@GET
@Path("/resourceOne")
@AnnotationForResourceOne
public String getResourceOne() {...}
}
2. Use DynamicFeature:
2. 使用动态特征:
2.1. Create filter:
2.1. 创建过滤器:
public class ResourceOneFilter implements ContainerRequestFilter {
...
}
2.2. Implement javax.ws.rs.container.DynamicFeature interface:
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);
}
}
}
In this scenario:
在这种情况下:
- filter is not annotated with
@Provider
annotation; configure(...)
method is invoked for every resource method;ctx.register(filter)
binds filter with resource method;
- 过滤器没有注解
@Provider
注解; configure(...)
为每个资源方法调用方法;ctx.register(filter)
将过滤器与资源方法绑定;
回答by Arun Avanathan
When we use @NameBinding
we need to remove @PreMatching
annotation from the Filter. @PreMatching
causes all the requests go through the filter.
当我们使用时,@NameBinding
我们需要@PreMatching
从过滤器中删除注释。@PreMatching
导致所有请求都通过过滤器。
回答by Christian Brugger
@PreMatching
does not work together with @NameBinding
, because the resource class/method is not yet known in pre-matching phase.
I solved this issue by removing @PreMatching
from the filter and using binding priority. See ResourceConfig.register(Object component, int bindingPriority)
.
@PreMatching
不能与 一起使用@NameBinding
,因为在预匹配阶段还不知道资源类/方法。我通过@PreMatching
从过滤器中删除并使用绑定优先级解决了这个问题。见ResourceConfig.register(Object component, int bindingPriority)
。
Filters to be executed before the resource simply get a higher priority.
在资源之前执行的过滤器只是获得更高的优先级。