2012-07-06 10 views
8

Estoy escribiendo una API REST, haciendo uso de RestEasy 2.3.4.Final. Sé que un Interceptor interceptará todas mis solicitudes, y que un PreProcessInterceptor será el primero (antes de todo) a ser llamado. Me gustaría saber cómo puedo llamar a este Interceptor solo cuando se llaman métodos específicos.¿Cómo utilizar RESTEasy PreProcessInterceptor solo en métodos específicos?

Intenté usar PreProcessInterceptor y AcceptedByMethod, pero no pude leer los parámetros que necesito. Por ejemplo, se necesita para ejecutar mi interceptor sólo cuando se llama a este método:

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

Para ser más específicos, se necesita para ejecutar mi interceptor en todos los métodos cuyos tener un @QueryParam("name")

de su firma, para poder agarrar el nombre y hacer algo antes de todo.

¿Es posible? Intenté capturar el parámetro "nombre" dentro del Interceptor, pero no pude hacer eso.

¿Alguien podría ayudarme, por favor?

Respuesta

7

Puede utilizar AcceptedByMethod como se explica en el RESTEasy documentation

Crear una clase que implementan tanto PreProcessInterceptor y AcceptedByMethod. En el método accept, puede verificar si el método tiene un parámetro anotado con @QueryParam("name"). Si el método tiene esa anotación, devuelva true del accept -metodo.

En el método preProcess, puede obtener el parámetro de consulta de request.getUri().getQueryParameters().getFirst("name").

EDIT:

He aquí un ejemplo:

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

Gracias @eiden. Intenté esto antes, pero sin usar el '@ Contexto'. Pero, cuando trato de recuperar algunos datos del contexto inyectado, arroja una excepción porque el contexto no se inicializó, supongo. org.apache.catalina.core.ContainerBase. [Jboss.web]. [Predeterminado-host]. [/ Api]] (subproceso de servicio MSC 1-3) Excepción que envía el evento inicializado de contexto a la instancia de escucha de la clase org.jboss .resteasy.plugins.server.servlet.ResteasyBootstrap: org.jboss.resteasy.spi.LoggableFailure: no se pueden encontrar datos contextuales de tipo: javax.servlet.http.HttpServletRequest – pulu

+0

¿No sé por qué está utilizando @Context? De todos modos, he actualizado mi respuesta con un ejemplo de código – eiden

+0

Excelente @eiden. Casi lo tengo trabajando de esa manera, pero no me di cuenta 'if (annotation.annotationType() == QueryParam.class) { QueryParam queryParam = (QueryParam) anotación; return queryParam.value(). Equals ("name"); ' ¡Muchas gracias por ayudarme! Y espero que ayude a algunas personas más. – pulu

2

si regresa return new ServerResponse(responseText, 200, new Headers<Object>());, perderá el punto final. debe devolver null si aún desea que el mensaje se entregue en el punto final.

Cuestiones relacionadas