从多个 HTTP 请求中提取和累积结果
Extracting and accumulate result from multiple HTTP request
这几天遇到了一个无法解决的问题。我正在执行多个 http 请求,在每个响应中,它应该有一个 Array[DTAnnotation]
。我想将所有结果列表累积成一个(这不是这里的问题)。我的问题是我无法 return 来自 WSResponse
的结果。我的尝试:
import mymodel.{DTFeatures, DTResponse, DTRequest, DTAnnotations}
def checkForSpike
(
awsKey : String,
collection : JSONCollection,
record : Record,
features : Array[DTFeatures]
) : Unit = {
val url = config.getString("url").getOrElse
val holder = WS.url(url)
val complexHolder =
holder.withHeaders(("Content-Type","application/json"))
// excepting result is List[Array[DTAnnotations]]
val test : List[Array[DTAnnotations]] =
for(feature <- features) yield {
val dtFeature = Json.stringify(Json.toJson(DTRequest(feature)))
val futureResponse = complexHolder.post(dtFeature)
Logger.info("Make the HTTP POST Request in " + (t1 - t0) + " msecs")
futureResponse.map { response =>
Logger.info("Get response in " + (System.currentTimeMillis - t1))
if(response.status == 200) {
response.json.validate[DTResponse].map { dtResponse =>
// I want to return this
dtResponse.annotations
}.recoverTotal { _ =>
Logger.debug("invalid json")
}
} else {
Logger.debug(Json.prettyPrint(Json.obj("status" -> response.status, "body" -> response.body)))
}
}
Await.result(futureResponse, 10.seconds)
}
}
因为响应是 Future
,我尝试添加一个 Await
来获取注释,但我在输入阶段有一个错误:
[error] found : Array[play.api.libs.ws.WSResponse]
[error] required: List[Array[DTAnnotation]]
我该如何解决这个问题?谢谢!
有许多错误可以避免此操作。我添加了一个与您期望的类型编译的版本,如果您有任何问题,我会在评论中回答。
def checkForSpike
(
awsKey: String,
collection: JSONCollection,
record: Record,
features: Array[DTFeatures]
): Unit = {
val url = config.getString("url").getOrElse
val holder = WS.url(url)
val complexHolder =
holder.withHeaders(("Content-Type", "application/json"))
// excepting result is List[Array[DTAnnotations]]
val test: List[Array[DTAnnotations]] =
for (feature <- features.toList) yield {
val dtFeature = Json.stringify(Json.toJson(DTRequest(feature)))
val futureResponse = complexHolder.post(dtFeature)
val futureAnnotations: Future[Array[DTAnnotations]] = futureResponse.map { response =>
if (response.status == 200) {
response.json.validate[DTResponse].map { dtResponse =>
// I want to return this
dtResponse.annotations
}.recoverTotal { _ =>
Logger.debug("invalid json")
??? // An Array response should be expected, maybe empty
}
} else {
Logger.debug(Json.prettyPrint(Json.obj("status" -> response.status, "body" -> response.body)))
??? // An Array response should be expected, maybe empty
}
}
Await.result(futureAnnotations, 10.seconds)
}
}
问题:
- 如果您希望列表成为要素,则必须将要素转换为列表
由 for comprehension
返回
- 未来响应地图returns
另一个未来,这个值应该用在 Await
- 为了确保 futureAnnotations 的类型在所有分支中都是正确的,类型应该是有效的
这几天遇到了一个无法解决的问题。我正在执行多个 http 请求,在每个响应中,它应该有一个 Array[DTAnnotation]
。我想将所有结果列表累积成一个(这不是这里的问题)。我的问题是我无法 return 来自 WSResponse
的结果。我的尝试:
import mymodel.{DTFeatures, DTResponse, DTRequest, DTAnnotations}
def checkForSpike
(
awsKey : String,
collection : JSONCollection,
record : Record,
features : Array[DTFeatures]
) : Unit = {
val url = config.getString("url").getOrElse
val holder = WS.url(url)
val complexHolder =
holder.withHeaders(("Content-Type","application/json"))
// excepting result is List[Array[DTAnnotations]]
val test : List[Array[DTAnnotations]] =
for(feature <- features) yield {
val dtFeature = Json.stringify(Json.toJson(DTRequest(feature)))
val futureResponse = complexHolder.post(dtFeature)
Logger.info("Make the HTTP POST Request in " + (t1 - t0) + " msecs")
futureResponse.map { response =>
Logger.info("Get response in " + (System.currentTimeMillis - t1))
if(response.status == 200) {
response.json.validate[DTResponse].map { dtResponse =>
// I want to return this
dtResponse.annotations
}.recoverTotal { _ =>
Logger.debug("invalid json")
}
} else {
Logger.debug(Json.prettyPrint(Json.obj("status" -> response.status, "body" -> response.body)))
}
}
Await.result(futureResponse, 10.seconds)
}
}
因为响应是 Future
,我尝试添加一个 Await
来获取注释,但我在输入阶段有一个错误:
[error] found : Array[play.api.libs.ws.WSResponse]
[error] required: List[Array[DTAnnotation]]
我该如何解决这个问题?谢谢!
有许多错误可以避免此操作。我添加了一个与您期望的类型编译的版本,如果您有任何问题,我会在评论中回答。
def checkForSpike
(
awsKey: String,
collection: JSONCollection,
record: Record,
features: Array[DTFeatures]
): Unit = {
val url = config.getString("url").getOrElse
val holder = WS.url(url)
val complexHolder =
holder.withHeaders(("Content-Type", "application/json"))
// excepting result is List[Array[DTAnnotations]]
val test: List[Array[DTAnnotations]] =
for (feature <- features.toList) yield {
val dtFeature = Json.stringify(Json.toJson(DTRequest(feature)))
val futureResponse = complexHolder.post(dtFeature)
val futureAnnotations: Future[Array[DTAnnotations]] = futureResponse.map { response =>
if (response.status == 200) {
response.json.validate[DTResponse].map { dtResponse =>
// I want to return this
dtResponse.annotations
}.recoverTotal { _ =>
Logger.debug("invalid json")
??? // An Array response should be expected, maybe empty
}
} else {
Logger.debug(Json.prettyPrint(Json.obj("status" -> response.status, "body" -> response.body)))
??? // An Array response should be expected, maybe empty
}
}
Await.result(futureAnnotations, 10.seconds)
}
}
问题:
- 如果您希望列表成为要素,则必须将要素转换为列表 由 for comprehension 返回
- 未来响应地图returns 另一个未来,这个值应该用在 Await
- 为了确保 futureAnnotations 的类型在所有分支中都是正确的,类型应该是有效的