2012-07-06 10 views
8

Piszę REST API, korzystając z RestEasy 2.3.4.Final. Wiem, że Interceptor przechwyci wszystkie moje żądania i że PreProcessInterceptor będzie pierwszym (przed wszystkim), który ma zostać wywołany. Chciałbym wiedzieć, w jaki sposób mogę uczynić ten Interceptor tak zwanym, gdy zostaną określone określone metody.Jak używać RESTEasy PreProcessInterceptor tylko w określonych metodach?

Próbowałem użyć obu PreProcessInterceptor i AcceptedByMethod, ale nie byłem w stanie odczytać potrzebnych parametrów. Na przykład, muszę uruchomić mój Interceptor tylko wtedy, gdy ta metoda nazywa się:

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

Aby być bardziej konkretne, trzeba uruchomić mój Interceptor we wszystkich metod, których mają @QueryParam("name")

na jego podpis, aby móc zdobyć imię i zrobić coś przed wszystkim.

Czy to możliwe? Próbowałem złapać parametr "name" wewnątrz Interceptora, ale nie byłem w stanie tego zrobić.

Czy ktoś może mi pomóc, proszę?

Odpowiedz

7

Można użyć AcceptedByMethod jak wyjaśniono w RESTEasy documentation

Tworzenie klasy, które implementują zarówno PreProcessInterceptor i AcceptedByMethod. W metodzie accept można sprawdzić, czy metoda ma parametr z przypisami z @QueryParam("name"). Jeśli metoda ma tę adnotację, zwróć true z metody accept.

W metodzie preProcess można uzyskać parametr zapytania od request.getUri().getQueryParameters().getFirst("name").

EDIT:

Oto przykład:

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. Próbowałem tego wcześniej, ale bez użycia '@ Context'. Ale kiedy próbuję odzyskać dane z wstrzykniętego kontekstu, generuje wyjątek, ponieważ kontekst nie został zainicjowany, jak sądzę. org.apache.catalina.core.ContainerBase. [Jboss.web]. [Default-host]. [/ Api]] (wątek usługi MSC 1-3) Zainicjowane zdarzenie inicjowania zdarzenia wyjątku do instancji odbiornika klasy org.jboss .resteasy.plugins.server.servlet.ResteasyBootstrap: org.jboss.resteasy.spi.LoggableFailure: Nie można znaleźć danych kontekstowych typu: javax.servlet.http.HttpServletRequest – pulu

+0

Nie wiem, dlaczego używasz @Context? W każdym razie, zaktualizowałem swoją odpowiedź kodem przykładowym – eiden

+0

Excelent @eiden. Prawie mam to działa w ten sposób, ale nie zrealizowałem 'if (adnotation.annotationType() == QueryParam.class) { QueryParam queryParam = (QueryParam) adnotacja; return queryParam.value(). Equals ("name"); ' Wielkie dzięki za pomoc! Mam nadzieję, że pomoże to większej liczbie osób. – pulu

2

jeśli wrócisz return new ServerResponse(responseText, 200, new Headers<Object>()); stracisz punktu końcowego. musisz zwrócić null, jeśli nadal chcesz, aby wiadomość dotarła do ostatniego punktu.

Powiązane problemy