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