2014-05-13 8 views
16

Ich versuche, eine Validierung für Anfragen in meinem Service mit der ContainerRequestFilter zu tun. Alles funktioniert gut, aber es gibt ein Problem - jede einzelne Anfrage wird durch die Filter geleitet, obwohl einige der Filter nie auf sie angewendet werden (ein Filter validiert nur auf ResourceOne, ein anderer nur auf ResourceTwo usw.)Jersey Request Filter nur auf bestimmten URI

Gibt es eine Möglichkeit, einen Filter so einzurichten, dass er nur unter bestimmten Bedingungen auf einer Anfrage aufgerufen wird?

Während es nicht ein Blocker oder hinderlich ist, wäre es schön, der Lage sein, diese Art von Verhalten zu stoppen :)

Antwort

37

Ich gehe davon aus, dass Sie verwenden Jersey 2.x (Implementierung für JAX-RS 2.0 API).

Sie haben zwei Möglichkeiten, Ihr Ziel zu erreichen.

1. Name verwenden Bindungen:


1,1 benutzerdefinierte Anmerkung mit @NameBinding kommentierten erstellen:

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

1,2. Erstellen Sie einen Filter mit Ihrer Anmerkung:

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

1.3. Und BIND erstellt Filter mit ausgewählten Ressourcen Methode:

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

2. Verwenden DynamicFeature:


2,1. Filter erstellen:

public class ResourceOneFilter implements ContainerRequestFilter { 
... 
} 

2.2. Implementieren javax.ws.rs.container.DynamicFeature Schnittstelle:

@Provider 
public class MaxAgeFeature implements DynamicFeature { 
    public void configure(ResourceInfo ri, FeatureContext ctx) { 
     if(resourceShouldBeFiltered(ri)){ 
      ResourceOneFilter filter = new ResourceOneFilter(); 
      ctx.register(filter); 
     } 
    } 
} 

In diesem Szenario:

  • Filter nicht mit @Provider Anmerkung kommentiert;
  • configure(...) Methode wird für jede Ressourcenmethode aufgerufen;
  • ctx.register(filter) bindet Filter mit Ressourcenmethode;
+0

Das DynamicFeature funktionierte wie ein Charme. –

+5

Sind Sie sicher, dass die Annotation "@ PreMatching" im Beispiel "NameBinding" benötigt wird? – Zakhar

+0

Namensbindungen funktionierten nicht für mich – Kunal

7

Wenn wir @NameBinding verwenden, müssen wir @PreMatching Annotation aus dem Filter entfernen. @PreMatching bewirkt, dass alle Anforderungen den Filter durchlaufen.

1

@PreMatching funktioniert nicht zusammen mit @NameBinding, weil die Ressourcenklasse/Methode in Pre-Matching-Phase noch nicht bekannt ist. Ich löste dieses Problem, indem ich @PreMatching aus dem Filter entfernte und Bindungspriorität verwendete. Siehe ResourceConfig.register(Object component, int bindingPriority).

Filter, die vor der Ressource ausgeführt werden, erhalten einfach eine höhere Priorität.

Verwandte Themen