vertx 组合期货并在发生故障时结束响应。
一个请求想要执行以下步骤
- 从 mongodb 查询一个文档
- 检查它是否有字段名称。如果它有该字段,则以状态码 409 结束响应
- 如果没有字段名,则调用异步 api 来获取 JsonObject
- 从 JsonObject 获取一个字段并用它更新第一个文档中的字段名称
private Future<JsonObject> findADocument(String id) {
return mongoClient.findOne(COLLECTION, new JsonObject().put("id", id), null);
}
private Future<JsonObject> requestAnAsync(JsonObject jsonObject) {
return Future.succeededFuture(new JsonObject());
}
private Future<JsonObject> check(Future<JsonObject> futureContent, String id) {
return futureContent.map(jsonObject -> {
String name = jsonObject.getString("name");
if (name != null) {
throw new DeployedException("Deployed already");
}
return jsonObject;
});
}
private Future<MongoClientUpdateResult> update22(JsonObject jsonObject) {
String name = jsonObject.getString("name");
JsonObject query = new JsonObject()
.put("id", "");
JsonObject update = new JsonObject().put("$set", new JsonObject()
.put("name", name));
UpdateOptions options = new UpdateOptions().setMulti(false).setUpsert(false);
return mongoClient.updateCollectionWithOptions(COLLECTION, query, update, options);
}
private void handleARequest(RoutingContext routingContext) {
HttpServerResponse response = routingContext.response();
String id = routingContext.request().getParam("id");
Future<JsonObject> futureContent = findADocument(id);
futureContent = check(futureContent, id);
// hope to end response in the middle of the chain
// but found these two onFailure handler would be executed
futureContent.onFailure(err -> {
if (err instanceof DeployedException) {
DeployedException deployedException = (DeployedException) err;
logger.error(deployedException.getMessage());
sendError(409, deployedException.getMessage(), response);
} else {
err.printStackTrace();
routingContext.response().setStatusCode(500).end("failed");
}
});
Future<JsonObject> futureContent2 = futureContent.compose(this::requestAnAsync);
Future<MongoClientUpdateResult> updateFuture = futureContent2.compose(this::update22);
updateFuture.onSuccess(res -> {
if (res.getDocModified() == 1) {
System.out.println("updated !");
routingContext.response().end();
} else {
System.out.println("Not Found !");
routingContext.response().setStatusCode(404).end("Not Found");
}
}).onFailure(err -> {
if (err instanceof DeployedException) {
DeployedException deployedException = (DeployedException) err;
logger.error(deployedException.getMessage());
sendError(409, deployedException.getMessage(), response);
} else {
err.printStackTrace();
routingContext.response().setStatusCode(500).end("failed");
}
});
}
我希望在链的中间结束响应,但发现这两个 onFailure 处理程序将被执行。
(版本:Vert.X 4.1)