Jersey Request Filter only on certain URI

若如初见. 提交于 2019-12-17 18:23:05

问题


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


回答1:


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;



回答2:


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




回答3:


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



来源:https://stackoverflow.com/questions/23641345/jersey-request-filter-only-on-certain-uri

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!