2014-10-15 5 views
3

저는 클라이언트 측에서 Restlet을 사용하는 것에 관한 문서가 부족합니다.Restlet Client :: 필터를 추가하는 방법은 무엇입니까?

new ClientResource(url).get(); 

을하지만 서버가있는 ETag 헤더를 반환 할 수 있습니다 나는 ClientResource를 통해 서버의 자원을 얻고있다. 이것을 처리하기 위해 반환 될 때 ETag를 저장하고 동일한 URL을 사용할 때 서버로 다시 보내려고합니다. 는 현재 내가 이런 식으로 일을하고있다 :

ClientResource clientResource = new ClientResource(url); 
addEtag(url, clientResource); // add the cached ETag to the query if any 
clientResource.get(); 
saveEtag(url, clientResource); // cache the ETag if any 

내가 Restlet 프레임 워크를 사용하여이 작업을 수행하고 싶습니다. 나는 누락 된 링크를 이해하는 날을 찾고 있습니다. 나는 createOutboundRoot() 메소드를 덮어 응용 프로그램을 확장하고 반환하는 필터 할 수 있습니다

public class RestLetClient extends Application { 

    private Client client; 

    // instantiation of the client and other things here 

    @Override 
    public Restlet createOutboundRoot() { 
     return new Filter(getContext(), client){ 

      @Override 
      protected int beforeHandle(Request request, Response response) { 
       addEtag(request); 
       return super.doHandle(request, response); 
      } 

      @Override 
      protected void afterHandle(Request request, Response response) { 
       saveEtag(request, reponse); 
       return super.afterHandle(request, response); 
      } 
     }; 
    } 
} 

을하지만 어떻게 내 비즈니스 코드에서 Restlet 프레임 클라이언트 주변이 필터링을 사용할 수 있습니까?

편집

지금까지 작동시킬 수있는 최선은 이것이다 :

Request request = new Request(Method.GET, uri); 
//the filter created in original post 
filter.handle(request).getEntity(); 

이 작동하지만이 프레임 워크에 통합되어 있지 않습니다. 내가 성취하고자하는 것은 서버쪽에 대해서만 문서화 된 것입니다. 서버에서 다음을 수행하십시오.

public class ServerApplication extends Application { 

    @Override 
    public Restlet createInboundRoot() { 
     Router router = new Router(getContext()); 
     router.attach(GET_URL, GetResource.class); 
     return router; 
    } 
} 

그런 다음 서버를 시작하십시오. 응용 프로그램은 URL에 대한 GET 요청 수신시 트리거됩니다.
클라이언트 측에서 동등한 것은 무엇입니까? 클라이언트 응용 프로그램을 어떻게 트리거 할 수 있습니까? : 나는 클라이언트 측에서 실행되는 응용 프로그램이 있다면 나는 잘 그들이 REST 응용 프로그램

EDIT 2

나는 오류가 응용 프로그램 내에서 내 클라이언트를 실행하려고에 속하지 필터를 추가 할 수 있습니다 필터 [email protected]는 다음 Restlet이 첨부되지 않은 채 실행되었습니다.

다음은 오류를 얻는 방법입니다. 하나의 시험 방법

public class RestLetClient extends Application { 

    private final Client client; 

    Logger logger = LoggerFactory.getLogger(getClass()); 

    public RestLetClient() { 
     this.client = new Client(Protocol.HTTP); 
    } 

    public Representation get(final String uri) throws Exception { 

     Request request = new Request(Method.GET, uri); 
     Response response = handle(request); 
     return response.getEntity(); 
    } 

    @Override 
    public Restlet createOutboundRoot() { 
     return new Filter(getContext(), client) { 
      @Override 
      protected int beforeHandle(Request request, Response response) { 
       addEtagFilter(request); 
       return super.beforeHandle(request, response); 
      } 

      @Override 
      protected void afterHandle(Request request, Response response) { 
       saveEtagFilter(request, response); 
       super.afterHandle(request, response); 
      } 
     }; 
    } 

    private void saveEtagFilter(Request request, Response response) { 
     logger.debug("saving etag"); 
    } 

    private void addEtagFilter(Request request) { 
     logger.debug("adding etag"); 
    } 
} 

와 단위 :

public class RestLetClientTest { 

    public static final String URL = "http://localhost:8123/resource"; 

    private RestLetClient instance; 

    private Server server; 

    @Before 
    public void setUp() throws Exception { 
     server = new Server(Protocol.HTTP, 8123, new TestApplication()); 

     server.start(); 

     instance = new RestLetClient(); 
     instance.start(); 
    } 

    @After 
    public void tearDown() throws Exception { 
     instance.stop(); 
    } 

    @Test 
    public void testGet() throws Exception { 
     Representation representation = instance.get(URL); 
     System.out.println(representation.getText()); 
    } 

    private class TestApplication extends Application { 
     @Override 
     public Restlet createInboundRoot() { 
      return new Router().attach(RestLetClientTest.URL, GetResource.class); 
     } 
    } 

    private class GetResource extends ServerResource { 
     @Get 
     public Representation getResource() { 
      return new StringRepresentation("hello world"); 
     } 
    } 
} 

내가 잘못하고있는 중이 야 내가 클래스 확장 JUnit 테스트에서 호출 응용 프로그램이 있습니까?

답변

2

나는 동료에게서 훨씬 좋은 답변을 얻었다. 나는 여기에 문서를 게시한다.

해결 방법은 ClientResource, 필터 및 클라이언트를 사용하는 것입니다. 필터는 ClientResource의 next()가되고 Client는 Filter의 next()가됩니다.

public class ETagFilter extends Filter { 

    @Override 
    protected int beforeHandle(Request request, Response response) { 
     addEtag(request); 
     return super.beforeHandle(request, response); 
    } 

    @Override 
    protected void afterHandle(Request request, Response response) { 
     saveEtag(request, reponse); 
     super.afterHandle(request, response); 
    } 
} 

public class RestLetClient extends Application { 

    public Representation get(final String uri) throws Exception { 

     Client client = new Client(Protocol.HTTP); 
     ETagFilter eTagFilter = new ETagFilter(); 
     clientResource = new ClientResource(uri); 

     clientResource.setNext(eTagFilter); 
     eTagFilter.setNext(client); 

     return clientResource.get(halMediaType); 
    } 
} 

정보 용. 내 OP에서 나는 클라이언트 측으로 서버 측을위한 코드를 변형하려고 노력했다. 그 접근법은 잘못되었습니다. 제 동료는 비슷한 접근 방식을 사용하는 Apache HttpClient와 훨씬 비슷하다는 점을 지적했습니다

+0

RIAP에서도이 작업을 한 번 해보았습니까? https://stackoverflow.com/questions/46224042/how-to-filter-or-intercept-restlet-riap-requests – danirod

1

클라이언트가 작동하도록하려면 javadoc에 따라 서버 지향적이므로 응용 프로그램을 그림 밖으로 가져와야합니다.

필요한 것은 Component, ClientRouter 및 사용자 정의 ClientRoute입니다.

  • 구성 요소 관리 커넥터. Restlet Client는 커넥터입니다.
  • ClientRouter가 클라이언트 커넥터에 전달됩니다.
  • ClientRoute는 클라이언트 주변에 필터를 추가 할 수 있도록 필터를 확장합니다.

내 솔루션 :
컴포넌트

public class RestLetComponent extends Component { 

    public RestLetComponent(Client client) { 
     getClients().add(client); 
    } 
} 

ClientRouter

public class RestLetClientRouter extends ClientRouter { 

    public RestLetClientRouter(final Client client) { 
     super(new RestLetComponent(client)); 
     ClientRoute clientRoute = new RestLetClientRoute(this, client); 
     //forcing to use only our custom route 
     getRoutes().clear(); 
     getRoutes().add(clientRoute); 
    } 

    public Representation get(final String uri) throws Exception { 
     Request request = new Request(Method.GET, uri); 
     Response response = handle(request); 
     return response.getEntity(); 
    } 
} 

그리고 필터를 추가합니다 사용자 정의 ClientRoute

public class RestLetClientRoute extends ClientRoute { 

    Logger logger = LoggerFactory.getLogger(getClass()); 

    public RestLetClientRoute(Router router, Client client) { 
     super(router, client); 
    } 

    //the filters 
    @Override 
    protected int beforeHandle(Request request, Response response) { 
     addEtagFilter(request); 
     return super.beforeHandle(request, response); 
    } 

    @Override 
    protected int doHandle(Request request, Response response) { 
     logger.debug("handling request: " + request.getMethod() + " - " + request.getResourceRef()); 
     return super.doHandle(request, response); 
    } 

    @Override 
    protected void afterHandle(Request request, Response response) { 
     saveEtagFilter(request, response); 
     super.afterHandle(request, response); 
    } 

    private void saveEtagFilter(Request request, Response response) { 
     logger.debug("saving etag"); 
    } 

    private void addEtagFilter(Request request) { 
     logger.debug("adding etag"); 
    } 
} 

마지막으로 중요한 것은 입니다. Restlet의 저자 인에게 사과 드리며, 그 문서가 있습니다. Restlet in Action 책을 읽었는데 그 대답은 잘 설명 된 javadoc에 있습니다.

관련 문제