2012-07-06 26 views
8

Tôi đang viết một API REST, sử dụng RestEasy 2.3.4.Final. Tôi biết rằng một Interceptor sẽ chặn tất cả các yêu cầu của tôi, và rằng một PreProcessInterceptor sẽ là người đầu tiên (trước khi mọi thứ) được gọi. Tôi muốn biết làm thế nào tôi có thể làm cho Interceptor này được gọi khi các phương thức cụ thể được gọi.Làm thế nào để sử dụng RESTEasy PreProcessInterceptor chỉ trong các phương pháp cụ thể?

Tôi đã cố gắng sử dụng cả PreProcessInterceptor và AcceptedByMethod, nhưng tôi không thể đọc các tham số tôi cần. Ví dụ, tôi cần phải chạy Interceptor của tôi chỉ khi phương pháp này được gọi là:

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

Để cụ thể hơn, tôi cần phải chạy Interceptor của tôi trong tất cả các phương pháp mà có một @QueryParam("name")

trên chữ ký của mình, để tôi có thể lấy tên và làm điều gì đó trước mọi thứ.

Có thể không? Tôi đã cố gắng nắm bắt thông số "tên" bên trong Interceptor, nhưng tôi không thể làm điều đó.

Ai đó có thể giúp tôi không?

Trả lời

7

Bạn có thể sử dụng AcceptedByMethod như được giải thích trong RESTEasy documentation

Tạo một lớp mà thực hiện cả hai PreProcessInterceptorAcceptedByMethod. Trong phương thức accept, bạn có thể kiểm tra xem phương thức có tham số có chú thích với @QueryParam("name") hay không. Nếu phương thức có chú thích đó, trả về true từ phương thức accept.

Trong phương thức preProcess, bạn có thể nhận tham số truy vấn từ request.getUri().getQueryParameters().getFirst("name").

EDIT:

Dưới đây là một ví dụ:

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. Tôi đã thử điều này trước đây, nhưng không sử dụng '@ Context'. Nhưng, khi tôi cố gắng lấy một số dữ liệu từ ngữ cảnh được tiêm, nó ném ra một ngoại lệ vì ngữ cảnh không được khởi tạo, tôi đoán vậy. org.apache.catalina.core.ContainerBase. [Jboss.web]. [Máy ​​chủ lưu trữ mặc định]. [/ Api]] (Chuỗi dịch vụ MSC 1-3) Ngoại lệ gửi sự kiện khởi tạo bối cảnh đến thể hiện trình nghe của lớp org.jboss .resteasy.plugins.server.servlet.ResteasyBootstrap: org.jboss.resteasy.spi.LoggableFailure: Không thể tìm thấy dữ liệu theo ngữ cảnh của kiểu: javax.servlet.http.HttpServletRequest – pulu

+0

Tôi không biết tại sao bạn đang sử dụng @Context? Dù sao, tôi đã cập nhật câu trả lời của tôi với một ví dụ mã số – eiden

+0

Excelent @eiden. Tôi gần như đã nhận nó làm việc theo cách đó, nhưng tôi đã không nhận ra chú thích 'if (chú thích.annotationType() == QueryParam.class) { QueryParam queryParam = (QueryParam); trả về truy vấnParam.value(). Bằng ("name"); ' Rất cám ơn vì đã giúp tôi! Và tôi hy vọng nó sẽ giúp nhiều người hơn. – pulu

2

nếu bạn quay lại return new ServerResponse(responseText, 200, new Headers<Object>()); bạn sẽ mất hết điểm. bạn cần phải trả lại null nếu bạn vẫn muốn thư được gửi đến điểm cuối cùng.

Các vấn đề liên quan