【发布时间】:2014-07-01 17:21:07
【问题描述】:
我正在尝试使用ContainerRequestFilter 对进入我的服务的请求进行一些验证。一切正常,但是有一个问题 - 每个请求都会通过过滤器,即使某些过滤器永远不会应用于它们(一个过滤器仅在 ResourceOne 上验证,另一个仅在 ResourceTwo 上验证等)
有没有办法将过滤器设置为仅在特定条件下对请求调用?
虽然它不是阻碍或阻碍,但能够阻止这种行为会很好:)
【问题讨论】:
我正在尝试使用ContainerRequestFilter 对进入我的服务的请求进行一些验证。一切正常,但是有一个问题 - 每个请求都会通过过滤器,即使某些过滤器永远不会应用于它们(一个过滤器仅在 ResourceOne 上验证,另一个仅在 ResourceTwo 上验证等)
有没有办法将过滤器设置为仅在特定条件下对请求调用?
虽然它不是阻碍或阻碍,但能够阻止这种行为会很好:)
【问题讨论】:
我假设您使用的是 Jersey 2.x(JAX-RS 2.0 API 的实现)。
您有两种方法可以实现您的目标。
1.使用名称绑定:
1.1 创建带有@NameBinding 注解的自定义注解:
@NameBinding
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationForResourceOne {}
1.2。使用您的注释创建过滤器:
@Provider
@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) 将过滤器与资源方法绑定;【讨论】:
@PreMatching 注释吗?
@PreMatching,过滤器/拦截器将适用于所有请求,而不管注释如何使@NameBinding 无用。欲了解更多信息,请参阅jersey.java.net/documentation/latest/…
当我们使用@NameBinding 时,我们需要从过滤器中删除@PreMatching 注释。 @PreMatching 使所有请求都通过过滤器。
【讨论】:
@PreMatching 的删除拯救了这一天。
@PreMatching 不能与@NameBinding 一起使用,因为资源类/方法在预匹配阶段尚不清楚。
我通过从过滤器中删除@PreMatching 并使用绑定优先级解决了这个问题。见ResourceConfig.register(Object component, int bindingPriority)。
在资源获得更高优先级之前执行的过滤器。
【讨论】: