2012-07-06 10 views
8

Sto scrivendo un'API REST, facendo uso di RestEasy 2.3.4.Final. So che un Interceptor intercetterà tutte le mie richieste e che un PreProcessInterceptor sarà il primo (prima di tutto) a essere chiamato. Mi piacerebbe sapere come posso fare in modo che questo Interceptor venga chiamato solo quando vengono chiamati metodi specifici.Come utilizzare RESTEasy PreProcessInterceptor solo in metodi specifici?

Ho provato a utilizzare sia PreProcessInterceptor che AcceptedByMethod, ma non sono riuscito a leggere i parametri di cui ho bisogno. Per esempio, ho bisogno di eseguire il mio Interceptor solo quando questo metodo viene chiamato:

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

Per essere più precisi, ho bisogno di eseguire il mio Interceptor in tutti i metodi di cui avere un @QueryParam("name")

sulla sua firma, così posso prendere il nome e fare qualcosa prima di tutto.

È possibile? Ho provato a prendere il parametro "name" all'interno dell'Interceptor, ma non ero in grado di farlo.

Qualcuno potrebbe aiutarmi, per favore?

risposta

7

È possibile utilizzare AcceptedByMethod come spiegato nella RESTEasy documentation

Creare una classe che implementa sia PreProcessInterceptor e AcceptedByMethod. Nel metodo accept, è possibile verificare se il metodo ha un parametro annotato con @QueryParam("name"). Se il metodo ha quell'annotazione, restituisce true dal metodo accept.

Nel metodo preProcess, è possibile ottenere il parametro di query da request.getUri().getQueryParameters().getFirst("name").

EDIT:

Ecco un esempio:

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

Thankyou @eiden. L'ho provato prima, ma senza usare '@ Context'. Ma, quando provo a recuperare alcuni dati dal contesto iniettato, genera un'eccezione perché il contesto non è stato inizializzato, immagino. org.apache.catalina.core.ContainerBase. [Jboss.web]. [Default-host]. [/ Api]] (thread di servizio MSC 1-3) Exception sending context initialized event to listener instance of class org.jboss .resteasy.plugins.server.servlet.ResteasyBootstrap: org.jboss.resteasy.spi.LoggableFailure: impossibile trovare i dati contestuali di tipo: javax.servlet.http.HttpServletRequest – pulu

+0

Non so perché stai usando @Context? Ad ogni modo, ho aggiornato la mia risposta con un esempio di codice – eiden

+0

Excelent @eiden. Ho quasi capito che funzionava in quel modo, ma non mi ero reso conto che if (annotation.annotationType() == QueryParam.class) { QueryParam queryParam = (QueryParam) annotazione; return queryParam.value(). Equals ("name"); ' Molte grazie per avermi aiutato! E spero che aiuti altre persone. – pulu

2

se si torna return new ServerResponse(responseText, 200, new Headers<Object>()); si perde il punto finale. è necessario restituire null se si desidera che il messaggio venga consegnato al punto finale.