java - 使用 Java 在 Play 框架中链式 promise

标签 java playframework reactive-programming

我有一个 Controller 操作,我需要在其中调用第 3 方网络服务。

我的问题是我没有调用一个网络服务。我需要链接 4 到 5 个 Web 服务。我调用的每个 Web 服务都会返回一个我需要处理的 JSON 对象,并且根据一些逻辑我决定调用另一个 Web 服务(来自 4 个 Web 服务)或向调用者返回响应。这是我正在尝试做的事情:

 public static Promise<Result> accounts(){
    return WS.url("url1").get().map(response1 -> {
        JsonNode mynode = response1.asJson();

        if (mynode.get("status").asInt()==200){
            Promise<JsonNode> jsonPromise = WS.url("url2").get().map(response2->{
                    return response2.asJson();
            });
        }

        return ok(mynode);
        }); 
}

现在,根据文档,我认为我需要的是链接 promise ,其中每个 Web 服务调用都是一个 promise 。但我不确定该怎么做?

谢谢

最佳答案

他们称它为Reactive Composition,它是这样完成的 ->

public static Promise<Result> reactiveCombo() {
    Promise<WSResponse> promise1 = WS.url("url1").get();
    Promise<WSResponse> promise2 = WS.url("url2").get();
    Promise<WSResponse> promise3 = WS.url("url3").get();

    return promise1.flatMap(response1 -> {
        final JsonNode json1 = response1.asJson();
        if (!json1.has("someField")) {
            return Promise.promise(() -> badRequest());
        }
        return promise2.flatMap(response2 -> {
            final JsonNode json2 = response2.asJson();
            if (json1.get("someField").asText().equals(json2.get("someField").asText())) {
                return Promise.promise(() -> badRequest());
            }
            return promise3.map(response3 -> {
                final JsonNode json3 = response3.asJson();
                if (json3.get("boolField").asBoolean()) {
                    return badRequest();
                }
                return ok();
            });
        });
    });
}

对于大量调用,您可以使用 Promise.sequence() 并获得“创意”:

private static Promise<JsonNode> getPromise(String url, Predicate<JsonNode> predicate) {
    return WS.url(url).get().map(response -> {
        JsonNode json = response.asJson();           
        if (predicate.negate().test(json)) {
            throw new Exception("BUMMER!");
        }
        return json;
    });
}

public static Promise<Result> reactiveCombo(List<String> urls) {
    List<Promise<JsonNode>> promises = new ArrayList<Promise<JsonNode>>(urls.size());
    Predicate<String> predURL = p -> p.contains("goodApi");
    Predicate<JsonNode> pred1 = p -> p.has("boolField") && p.get("boolField").asBoolean();
    Predicate<JsonNode> pred2 = p -> p.has("someField");

    urls.forEach(url -> {
        Promise<JsonNode> promise = predURL.test(url) ? getPromise(url, pred1) : getPromise(url, pred2);           
        promises.add(promise);
    });

    return Promise.sequence(promises).map(results -> ok()).recover(t -> badRequest());
}

其他细节 + 纪录片:

Go Reactive with Java 8 & Play Framework (老了但仍然有教育意义)

JavaWS

关于java - 使用 Java 在 Play 框架中链式 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29617252/

相关文章:

sql - Play 2.4 - 在日志中显示 Ebeans SQL 语句

javascript - rxjs 将 Observable<List<X>> 转换为 Observable<X> 的运算符

java - 为什么 @JacksonXmlProperty 在使用 Kotlin 的 Spring Boot 中忽略参数?

java - 三元中的三元

java - 让 Play 框架和 Angular 一起工作的最佳方式

java - Play Framework : How to validate a subset of fields in an object?

javascript - 了解 rxjs 中的 SwitchMap

javascript - Rxjs 在 Observable 出错后传递数据

java - 为什么 String.split 需要转义管道分隔符?

java - 为什么存储长字符串会导致 OOM 错误,但将其分解为短字符串列表却不会?