質問

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.)

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).

You have two ways to achieve Your goal.

1. Use Name bindings:


1.1 Create custom annotation annotated with @NameBinding:

@NameBinding
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationForResourceOne {}

1.2. Create filter with Your annotation:

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

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.1. Create filter:

public class ResourceOneFilter implements ContainerRequestFilter {
...
}

2.2. Implement javax.ws.rs.container.DynamicFeature interface:

@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;

他のヒント

When we use @NameBinding we need to remove @PreMatching annotation from the Filter. @PreMatching causes all the requests go through the filter.

@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).

Filters to be executed before the resource simply get a higher priority.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top