2012-07-06 10 views
8

Ich schreibe eine REST-API, die RestEasy 2.3.4.Final verwendet. Ich weiß, dass ein Interceptor alle meine Anfragen abfängt, und dass ein PreProcessInterceptor der erste (vor allem) sein wird, der aufgerufen wird. Ich würde gerne wissen, wie ich diesen Interceptor nur dann aufrufen kann, wenn bestimmte Methoden aufgerufen werden.Wie wird der RESTEasy PreProcessInterceptor nur in bestimmten Methoden verwendet?

Ich habe versucht, sowohl PreProcessInterceptor und AcceptedByMethod zu verwenden, aber ich konnte nicht die Parameter lesen, die ich brauche. Zum Beispiel, ich brauche nur mein Interceptor laufen, wenn diese Methode aufgerufen wird:

@GET 
@Produces("application/json;charset=UTF8") 
@Interceptors(MyInterceptor.class) 
public List<City> listByName(@QueryParam("name") String name) {...} 

Um genauer zu sein, ich brauche meinen Interceptor in allen Methoden, deren ein @QueryParam("name")

auf seiner Unterschrift laufen, damit ich den Namen ergreifen und vor allem etwas machen kann.

Ist es möglich? Ich habe versucht, den Parameter "name" im Interceptor abzufangen, aber das war nicht möglich.

Könnte mir bitte jemand helfen?

Antwort

7

können Sie AcceptedByMethod verwenden, wie in der

RESTEasy documentation

erklärt Erstellen Sie eine Klasse, die sowohl PreProcessInterceptor und AcceptedByMethod implementieren. In der accept -Methode können Sie überprüfen, ob die Methode einen Parameter mit der Anmerkung @QueryParam("name") enthält. Wenn die Methode diese Annotation enthält, geben Sie true von der accept -Methode zurück. In der preProcess -Methode können Sie den Abfrageparameter von request.getUri().getQueryParameters().getFirst("name") abrufen.

EDIT:

Hier ist ein Beispiel:

public class InterceptorTest { 

    @Path("/") 
    public static class MyService { 

     @GET 
     public String listByName(@QueryParam("name") String name){ 
      return "not-intercepted-" + name; 
     } 
    } 

    public static class MyInterceptor implements PreProcessInterceptor, AcceptedByMethod { 

     @Override 
     public boolean accept(Class declaring, Method method) { 
      for (Annotation[] annotations : method.getParameterAnnotations()) { 
       for (Annotation annotation : annotations) { 
        if(annotation.annotationType() == QueryParam.class){ 
         QueryParam queryParam = (QueryParam) annotation; 
         return queryParam.value().equals("name"); 
        } 
       } 
      } 
      return false; 
     } 

     @Override 
     public ServerResponse preProcess(HttpRequest request, ResourceMethod method) 
       throws Failure, WebApplicationException { 

      String responseText = "intercepted-" + request.getUri().getQueryParameters().getFirst("name"); 
      return new ServerResponse(responseText, 200, new Headers<Object>()); 
     } 
    } 

    @Test 
    public void test() throws Exception { 
     Dispatcher dispatcher = MockDispatcherFactory.createDispatcher(); 
     dispatcher.getProviderFactory().getServerPreProcessInterceptorRegistry().register(new MyInterceptor()); 
     dispatcher.getRegistry().addSingletonResource(new MyService()); 

     MockHttpRequest request = MockHttpRequest.get("/?name=xxx"); 
     MockHttpResponse response = new MockHttpResponse(); 

     dispatcher.invoke(request, response); 

     assertEquals("intercepted-xxx", response.getContentAsString()); 
    } 
} 
+0

Danke @eiden. Ich habe das schon einmal versucht, aber ohne den '@ Context' zu verwenden. Aber wenn ich versuche, einige Daten aus dem injizierten Kontext abzurufen, löst es eine Exception aus, weil der Kontext nicht initialisiert wurde, nehme ich an. org.apache.catalina.core.ContainerBase. [Jboss.web]. [Standardhost]. [/ Api]] (MSC-Dienstthread 1-3) Exception sending context initialisiertes Ereignis an die Listener-Instanz der Klasse org.jboss .resteasy.plugins.server.servlet.ResteasyBootstrap: org.jboss.resteasy.spi.LoggableFailure: Konnte nicht finden kontextuelle Daten des Typs: javax.servlet.http.HttpServletRequest – pulu

+0

Ich weiß nicht, warum Sie @Context verwenden? Wie auch immer, ich habe meine Antwort mit einem Codebeispiel – eiden

+0

Excelent @eiden aktualisiert. Ich habe es fast so funktioniert, aber ich habe 'if (annotation.annotationType() == QueryParam.class) nicht erkannt { QueryParam queryParam = (QueryParam) Annotation; Rückgabe queryParam.value(). Equals ("name"); ' Vielen Dank für Ihre Hilfe! Und ich hoffe, es hilft ein paar mehr Menschen. – pulu

2

wenn Sie return new ServerResponse(responseText, 200, new Headers<Object>()); kehren Sie den Endpunkt verlieren. Sie müssen null zurückgeben, wenn Sie weiterhin möchten, dass die Nachricht an den letzten Punkt gesendet wird.