2012-07-06 14 views
8

私はRestEasy 2.3.4.Finalを使ってREST APIを書いています。 私はインターセプタが私の要求のすべてを傍受し、PreProcessInterceptorが呼び出される最初のもの(すべての前)であることを知っています。特定のメソッドが呼び出されたときに呼び出されるようにするには、どのようにしてこのインターセプタを呼び出すことができるかを知りたいと思います。特定のメソッドでのみRESTEasy PreProcessInterceptorを使用する方法はありますか?

PreProcessInterceptorとAcceptedByMethodの両方を使用しようとしましたが、必要なパラメータを読み取ることができませんでした。 は例えば、私は、このメソッドが呼び出されたときにのみ、私のインターセプタを実行する必要があります。

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

は、具体的には、私はそのその署名の@QueryParam("name")

を持っているすべてのメソッドで私のインターセプタを実行する必要があり、私は名前をつかんで、すべての前に何かをすることができます。

可能ですか?私はインターセプタ内の "名前"パラメータをキャッチしようとしましたが、それを行うことはできませんでした。

誰かが私を助けてくれますか?

答えて

7

PreProcessInterceptorAcceptedByMethodの両方を実装するクラスを作成しますRESTEasy documentation

で説明したようにあなたはAcceptedByMethodを使用することができます。 acceptメソッドでは、メソッドに@QueryParam("name")という注釈が付けられたパラメータがあるかどうかを確認できます。メソッドにその注釈がある場合は、acceptメソッドからtrueを返します。

preProcess -methodでは、クエリパラメータをrequest.getUri().getQueryParameters().getFirst("name")から取得できます。あなたは、エンドポイントを失うことになるreturn new ServerResponse(responseText, 200, new Headers<Object>());を返す場合

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

ありがとう@eiden。これを前に試してみましたが、 '@ Context'を使用しませんでした。しかし、注入されたコンテキストからデータを取得しようとすると、コンテキストが初期化されていないため例外がスローされます。 org.apache.catalina.core.ContainerBase [jboss.web]。[default-host]。[/ api]](MSCサービススレッド1-3)コンテキスト初期化イベントをorg.jbossクラスのリスナーインスタンスに送信する例外.resteasy.plugins.server.servlet.ResteasyBootstrap:org.jboss.resteasy.spi.LoggableFailure:javax.servlet.http.HttpServletRequestのコンテキストデータが見つかりません – pulu

+0

なぜ@Contextを使用しているのですか?とにかく、私は答えをコード例 – eiden

+0

Excelent @ eidenで更新しました。私はほとんどそのように働いていますが、私は 'if(annotation.annotationType()== QueryParam.class){ QueryParam queryParam =(QueryParam)注釈を実現しませんでした。 return queryParam.value()。equals( "name"); ' 多くの方に感謝します! そしてもっと多くの人々に役立つことを願っています。 – pulu

2

編集:ここでは

は一例です。最後のポイントにメッセージを引き渡す場合は、nullを返す必要があります。

関連する問題