java嵌套http调用API库

问题描述 投票:0回答:1

我正在阅读来自 playframework 的一些 http webservice API,链接如下。

我无法理解这种嵌套如何与平面图一起使用。

有人可以给我一些如何破解这一大块函数调用的提示吗?

来自 http://www.playframework.com/documentation/2.2.x/JavaWS

合成结果 如果您想按顺序拨打多个电话,
这可以使用 flatMap 来实现:

public static Promise<Result> index() {
    final Promise<Result> resultPromise = WS.url(feedUrl).get().flatMap(
           new Function<WS.Response, Promise<Result>>() {
                public Promise<Result> apply(WS.Response response) {
                    return WS.url(response.asJson().findPath("commentsUrl").asText()).get().map(
                        new Function<WS.Response, Result>() {
                            public Result apply(WS.Response response) {
                                return ok("Number of comments: " + response.asJson().findPath("count").asInt());
                            }
                        }
                );
            }
        }
);
    return resultPromise;
}
java web-services playframework
1个回答
1
投票

flatMap
map
是常见的 Scala(或更一般地说,函数式编程)函数。它们都接受 function 作为参数。为了将 Play WS API 转换为 Java(以及几乎所有其他内容),需要用 Java 重新实现 Scala 的函数类型,以便您可以充分利用 WS 库。这里的完成方式与 Scala 编译器类似。
Function<A,B>
是一个抽象类型,需要
apply
方法。
apply
的参数是函数的参数,
apply
的返回类型是函数的返回类型。

如果你的Java中有这个函数:

public String int2String(Integer integer) {
    return integer.toString();
}

这相当于:

new Function<Integer, String>() {
    public String apply(Integer integer) {
        return integer.toString();
    }
}

让我们从只有一个 WS 调用的情况开始更简单。

WS.url(...).get()
返回
Promise<WS.Response>
Promise
promised 值的容器类。为了处理它包含(或最终包含)的值,我们需要使用
map
函数。对于
Promise<WS.Response>
map
将接受
Function<WS.Response, T>
作为参数,其中
T
是要将响应映射到的类型。

作为示例,让我们定义一个

Function
,它将仅返回 Play HTTP 中
WS.Response
的主体
Result
:

Function<WS.Response, Result> echo = new Function<WS.Response, Result>() {
    public Result apply(WS.Response response) {
        return ok(response.asText());
    }
}

现在让我们在控制器的 WS 调用中使用这个

Function

public static Promise<Result> index() {

    final Promise<Result> resultPromise = WS.url("http://google.com").get().map(echo);

    return resultPromise;

}

一旦满足

Promise
,之前定义的
echo
函数将在
map
内部执行,返回
Promise<Result>
。前面的两段代码也可以这样写(用匿名函数合二为一):

public static Promise<Result> index() {

    final Promise<Result> resultPromise = WS.url("http://google.com").get().map(
        new Function<WS.Response, Result>() {
            public Result apply(WS.Response response) {
                return ok(response.asText());
            }
        }
    );

    return resultPromise;
}

作为一个粗略的例子,假设我们需要进行两次 WS 调用。第二个 WS 调用将取决于第一个 WS 调用。也许第一个调用会给我们一些 URL,我们将使用它来进行第二个 WS 调用。

这就是

flatMap
出现的地方。我们需要两个函数来完成这项任务。第一个函数是传递给
flatMap
的函数,它将在收到第一个
WS.Response
时执行。第一个函数将使用第一个响应进行第二个 WS 调用,该调用返回另一个必须映射才能获得最终结果的
Promise<WS.Response>
。因此,我们使用第二个函数将
map
转换为我们的
WS.Response

那么发生了什么?如果我们在这两种情况下都使用

Result

而不是

map
,事件链将如下所示:

第一个

flatMap

返回一个

get()
,然后我们将包含的
Promise<WS.Response>
返回到
map
。然而,这会给我们留下一个
WS.Response
,这不是很理想。在外部函数中使用
Promise<Result>
会将
Promise<Promise<WS.Response>>
展平为单个
flatMap
。同样,如果您进行 3 个或更多嵌套调用,您会将每个结果
Promise
传递给一个内部函数,并且在外部层只有一个
Promise<Result>
以在最后将所有内容展平。

这一切在 Scala 中当然看起来更漂亮。
    

© www.soinside.com 2019 - 2024. All rights reserved.