[英]Restlet Client :: how to add filters?
我缺乏在客戶端使用Restlet的文檔。 我通過ClientResource在服務器上獲取資源:
new ClientResource(url).get();
但是服務器可以返回ETag標頭。 為了解決這個問題,我想在返回時保存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應用程序的過濾器
編輯2
當嘗試在應用程序中運行我的客戶端時,我得到錯誤: 過濾器org.restlet.engine.application.RangeFilter@f372a7a在沒有附加下一個Restlet的情況下執行。
以下是我收到錯誤的方法。 我有一個擴展Application的類,它從JUnit測試中調用:
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");
}
}
}
我究竟做錯了什么?
我從一位同事那里得到了更好的回答。 我在這里發布文檔。
解決方案是使用ClientResource,Filter和Client。 Filter成為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來滿足類似的需求
要讓客戶端工作,您需要將應用程序從圖片中取出,因為它是根據javadoc面向服務器的。
您需要的是Component,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中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.