如何在Vertx路由器中使用futures和Java中的WebClient

如何在Vertx路由器中使用futures和Java中的WebClient,java,asynchronous,future,vert.x,web-client,Java,Asynchronous,Future,Vert.x,Web Client,我有一个带有路由器端点的Vertx应用程序: router.route(HttpMethod.GET, Constants.ENDPOINT).blockingHandler(this::getItems); 此路由器调用一个方法,该方法应返回浏览器中的JSON对象,或任何调用此端点的客户端。JSON对象实际上来自一个完全不同的服务。我正在使用Vert.x的WebClient库调用此服务 private void getItems(RoutingContext routingConte

我有一个带有路由器端点的Vertx应用程序:

router.route(HttpMethod.GET, Constants.ENDPOINT).blockingHandler(this::getItems);
此路由器调用一个方法,该方法应返回浏览器中的JSON对象,或任何调用此端点的客户端。JSON对象实际上来自一个完全不同的服务。我正在使用Vert.x的
WebClient
库调用此服务

    private void getItems(RoutingContext routingContext) {
    HttpServerResponse response = routingContext.response();
    response.setChunked(true);
    response.putHeader("content-type", "text/plain");
    response.putHeader("Access-Control-Allow-Origin", "*");
    JsonObject data = new JsonObject();
    WebClient webClient = WebClient.create(vertx);
    webClient.post(80, "my-site.com", "/api/items")
        .as(BodyCodec.jsonArray())
        .putHeader("Accept", "application/json")
        .putHeader("Content-Type", "application/json")
        .sendJsonObject(new JsonObject().put("mutator", "*"), ar -> {
            if (ar.succeeded()) {
                HttpResponse<JsonArray> result = ar.result();
                JsonArray body = result.body();
                System.out.println(body);
                data.put("data", body.getJsonObject(0));
            } else {
                data.put("data", ar.cause().getMessage());
            }
        }); 
    response.write(data.encode());
    routingContext.response().end();
}
private void getItems(RoutingContext RoutingContext){
HttpServerResponse=routingContext.response();
response.setChunked(true);
响应.putHeader(“内容类型”、“文本/普通”);
响应.putHeader(“访问控制允许原点”、“*”);
JsonObject数据=新的JsonObject();
WebClient-WebClient=WebClient.create(vertx);
webClient.post(80,“my site.com”,“/api/items”)
.as(BodyCodec.jsonArray())
.putHeader(“接受”、“应用程序/json”)
.putHeader(“内容类型”、“应用程序/json”)
.sendJsonObject(新JsonObject().put(“mutator”、“*”),ar->{
如果(ar.successed()){
HttpResponse result=ar.result();
JsonArray body=result.body();
系统输出打印项次(正文);
data.put(“data”,body.getJsonObject(0));
}否则{
data.put(“data”,ar.cause().getMessage());
}
}); 
response.write(data.encode());
routingContext.response().end();
}
我从
my site.com
获得的数据很好,并使用我的System.out命令显示在控制台中。问题是我无法让它进入
响应。写入

通过阅读,我发现这与期货有关。我真的不理解这个概念,所以我读了很多书,但找不到任何适合我特定代码的示例


我将如何实现未来,以便从
my site.com
接收的数据被放入我的Json对象(
data
),然后可以用于
响应。写入

impl数据中的数据将是空的Json对象,因为Webclient是异步的。在Webclient的响应准备就绪之前,您正在向客户端写入响应

将写入移动到webclient响应中,并在那里结束上下文。例如:

...

if (ar.succeeded()) { 
    HttpResponse<JsonArray> result = ar.result();
    JsonArray body = result.body();
    System.out.println(body); 
    data.put("data", body.getJsonObject(0));
} else { 
    data.put("data", ar.cause().getMessage());
}

response.write(data.encode());
routingContext.response().end();

...
。。。
如果(ar.successed()){
HttpResponse result=ar.result();
JsonArray body=result.body();
系统输出打印项次(正文);
data.put(“data”,body.getJsonObject(0));
}否则{
data.put(“data”,ar.cause().getMessage());
}
response.write(data.encode());
routingContext.response().end();
...

关于的Vert.x文档非常好,在示例中使用了futures。下面是我使用Vert.x futures实现它的方法:

private void getItems(RoutingContext routingContext) {
        HttpServerResponse response = routingContext.response();
        response.setChunked(true);
        response.putHeader("content-type", "text/plain");
        response.putHeader("Access-Control-Allow-Origin", "*");
        // init a future that should hold a JsonObject result
        Future<JsonObject> future = Future.future();
        JsonObject data = new JsonObject();
        WebClient webClient = WebClient.create(vertx);
        webClient.post(80, "my-site.com", "/api/items")
                .as(BodyCodec.jsonArray())
                .putHeader("Accept", "application/json")
                .putHeader("Content-Type", "application/json")
                .sendJsonObject(new JsonObject().put("mutator", "*"), ar -> {
                    if (ar.succeeded()) {
                        HttpResponse<JsonArray> result = ar.result();
                        JsonArray body = result.body();
                        System.out.println(body);
                        data.put("data", body.getJsonObject(0));
                        // set future to be completed, with data object as its JsonObject result
                        future.complete(data);
                    } else {
                         data.put("data", ar.cause().getMessage());
                         future.complete(data);
                         // we can also set the future as failed and give it a Throwable
                        // future.fail(ar.cause());
                    }
                });
        // handle when the future is completed
        future.setHandler(jsonObjectAsyncResult -> {
            if(jsonObjectAsyncResult.succeeded()) {
                response.write(data.encode());
                routingContext.response().end();
            }
        });
    }
private void getItems(RoutingContext RoutingContext){
HttpServerResponse=routingContext.response();
response.setChunked(true);
响应.putHeader(“内容类型”、“文本/普通”);
响应.putHeader(“访问控制允许原点”、“*”);
//初始化应该包含JsonObject结果的未来
Future=Future.Future();
JsonObject数据=新的JsonObject();
WebClient-WebClient=WebClient.create(vertx);
webClient.post(80,“my site.com”,“/api/items”)
.as(BodyCodec.jsonArray())
.putHeader(“接受”、“应用程序/json”)
.putHeader(“内容类型”、“应用程序/json”)
.sendJsonObject(新JsonObject().put(“mutator”、“*”),ar->{
如果(ar.successed()){
HttpResponse result=ar.result();
JsonArray body=result.body();
系统输出打印项次(正文);
data.put(“data”,body.getJsonObject(0));
//将future设置为completed,并将数据对象作为其JsonObject结果
未来。完成(数据);
}否则{
data.put(“data”,ar.cause().getMessage());
未来。完成(数据);
//我们也可以将未来设定为失败,并将其抛弃
//未来失败(ar.cause());
}
});
//未来完成时处理
future.setHandler(jsonObjectAsyncResult->{
if(jsonObjectAsyncResult.succeed()){
response.write(data.encode());
routingContext.response().end();
}
});
}