简体   繁体   English

泽西请求仅对某些URI进行过滤

[英]Jersey Request Filter only on certain URI

I am trying to do some validation on requests coming into my service using the ContainerRequestFilter . 我正在尝试使用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.) 一切都运行正常,但有一个问题 - 每个请求都通过过滤器,即使一些过滤器永远不会应用于它们(一个过滤器只在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 :) 虽然它不是阻碍或阻碍,但能够阻止这种行为会很好:)

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. 1.2。 Create filter with Your annotation: 使用您的注释创建过滤器:

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

1.3. 1.3。 And bind created filter with selected resource method: 并使用选定的资源方法绑定创建的过滤器

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

2. Use DynamicFeature: 2.使用DynamicFeature:


2.1. 2.1。 Create filter: 创建过滤器:

public class ResourceOneFilter implements ContainerRequestFilter {
...
}

2.2. 2.2。 Implement javax.ws.rs.container.DynamicFeature interface: 实现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; 过滤器未使用@Provider注释进行注释;
  • configure(...) method is invoked for every resource method; 为每个资源方法调用configure(...)方法;
  • ctx.register(filter) binds filter with resource method; ctx.register(filter)用资源方法绑定过滤器;

When we use @NameBinding we need to remove @PreMatching annotation from the Filter. 当我们使用@NameBinding我们需要从Filter中删除@PreMatching注释。 @PreMatching causes all the requests go through the filter. @PreMatching导致所有请求都通过过滤器。

@PreMatching does not work together with @NameBinding , because the resource class/method is not yet known in pre-matching phase. @PreMatching不能与@NameBinding一起使用,因为在预匹配阶段尚不知道资源类/方法。 I solved this issue by removing @PreMatching from the filter and using binding priority. 我通过从过滤器中删除@PreMatching并使用绑定优先级来解决此问题。 See ResourceConfig.register(Object component, int bindingPriority) . 请参阅ResourceConfig.register(Object component, int bindingPriority)

Filters to be executed before the resource simply get a higher priority. 在资源获得更高优先级之前要执行的过滤器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM