Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Java的Play框架中的链承诺_Java_Playframework_Reactive Programming - Fatal编程技术网

使用Java的Play框架中的链承诺

使用Java的Play框架中的链承诺,java,playframework,reactive-programming,Java,Playframework,Reactive Programming,我有一个控制器操作,需要调用第三方web服务 我的问题是我没有调用一个web服务。我需要在4到5个web服务之间建立链接。我调用的每个web服务都返回一个JSON对象,我需要对其进行处理,并根据某种逻辑决定调用另一个web服务(来自4个web服务)或向调用方返回响应。以下是我正在尝试做的: public static Promise<Result> accounts(){ return WS.url("url1").get().map(response1 -> {

我有一个控制器操作,需要调用第三方web服务

我的问题是我没有调用一个web服务。我需要在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);
        }); 
}
公共静态承诺账户(){
返回WS.url(“url1”).get().map(response1->{
JsonNode mynode=response1.asJson();
if(mynode.get(“status”).asInt()==200){
Promise jsonPromise=WS.url(“url2”).get().map(response2->{
返回response2.asJson();
});
}
返回ok(mynode);
}); 
}
现在,从文档中,我认为我需要的是链接承诺,其中每个web服务调用都是一个承诺。但我不知道该怎么做


谢谢

他们称之为反应性合成,就是这样做的->

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();
            });
        });
    });
}
其他详细信息+文档:

(古老但仍有教育意义)


您可以使用递归将此结构展平,以实现任意数量的承诺。 首先创建一个类:

public static class ChainedWebService {
    public final Optional<ChainedWebService> next;

    public final WSRequestHolder wsResponsePromise;
    private final F.Predicate<JsonNode> predicate;

    public ChainedWebService(String url, Optional<ChainedWebService> next, F.Predicate<JsonNode> predicate) {
        this.next = next;
        this.wsResponsePromise = WS.url(url);
        this.predicate = predicate;
    }

    public F.Promise<Result> processChain() {
        return wsResponsePromise.get().flatMap(new F.Function<WSResponse, F.Promise<Result>>() {
            @Override
            public F.Promise<Result> apply(WSResponse wsResponse) throws Throwable {
                if (!predicate.test(wsResponse.asJson())) {
                    return F.Promise.pure(badRequest());
                }

                if (!next.isPresent()) {
                    return F.Promise.pure(ok());
                }

                return next.get().processChain();
            }
        });
    }
}
公共静态类ChainedWebService{
公开最终选择下一步;
公共最终WSRequestHolder wsResponsePromise;
私有定语F.谓语;
public ChainedWebService(字符串url,可选下一步,F.谓词){
this.next=next;
this.wsResponsePromise=WS.url(url);
this.predicate=谓词;
}
公共F.承诺流程链(){
返回wsResponsePromise.get(){
@凌驾
公共F.承诺应用(WSResponse WSResponse)抛出可丢弃{
if(!predicate.test(wsResponse.asJson())){
返回F.Promise.pure(badRequest());
}
如果(!next.isPresent()){
返回F.Promise.pure(ok());
}
返回next.get().processChain();
}
});
}
}
然后使用它:

public static F.Promise<Result> reactiveCombo() {
    ChainedWebService chainedWebService3 = new ChainedWebService(
            "url3",
            Optional.<ChainedWebService>empty(),
            jsonNode -> jsonNode.get("boolField").asBoolean()
    );

    ChainedWebService chainedWebService2 = new ChainedWebService(
            "url2",
            Optional.of(chainedWebService3),
            jsonNode -> jsonNode.get("someField").asText().equals(jsonNode.get("someField").asText()));

    ChainedWebService chainedWebService1 = new ChainedWebService(
            "url1",
            Optional.of(chainedWebService2),
            jsonNode -> jsonNode.has("someField")
    );

    return chainedWebService1.processChain();
}
public static F.Promise reactiveCombo(){
ChainedWebService ChainedWebService 3=新的ChainedWebService(
“url3”,
可选。空(),
jsonNode->jsonNode.get(“boolField”).asBoolean()
);
ChainedWebService ChainedWebService 2=新的ChainedWebService(
“url2”,
可选。of(ChainedWebService 3),
jsonNode->jsonNode.get(“someField”).asText().equals(jsonNode.get(“someField”).asText());
ChainedWebService ChainedWebService 1=新的ChainedWebService(
“url1”,
可选。of(ChainedWebService 2),
jsonNode->jsonNode.has(“someField”)
);
返回chainedWebService1.processChain();
}
您可以实现一些基本生成器,使构建过程更加合理


希望这有帮助

好吧,这个很有魅力。然而,代码看起来很难看。我正在与一个DB服务器进行一些CRUD操作。我很清楚,可以对DB REST API进行大量改进,以减少调用数量,并提供安全的事务操作。但这不是我能做的。例如,在一个场景中,我最终调用了10个RESTAPI。因此,任何关于如何改进代码的建议,例如,您可以将URL放入数组中,对其进行迭代,并为每个URL创建一个
Promise
,添加到
列表promisesList
。然后可以使用
Promise.sequence(primisesList).map((List-resultList)->{…})。这将大大减少嵌套。这可能会有所帮助。我希望将来维护这个代码的人不知道我住在哪里:)嘿,来吧。。。没那么糟糕。这是一种有趣的方法,但您有
Promise.sequence()
正是为了实现这一点。另外,你真的有可能用这个解决方案填满堆栈。@sebster使用
Promise.sequence()
将意味着执行所有请求,在这种情况下这是不必要的。
public static F.Promise<Result> reactiveCombo() {
    ChainedWebService chainedWebService3 = new ChainedWebService(
            "url3",
            Optional.<ChainedWebService>empty(),
            jsonNode -> jsonNode.get("boolField").asBoolean()
    );

    ChainedWebService chainedWebService2 = new ChainedWebService(
            "url2",
            Optional.of(chainedWebService3),
            jsonNode -> jsonNode.get("someField").asText().equals(jsonNode.get("someField").asText()));

    ChainedWebService chainedWebService1 = new ChainedWebService(
            "url1",
            Optional.of(chainedWebService2),
            jsonNode -> jsonNode.has("someField")
    );

    return chainedWebService1.processChain();
}