从多个HTTP请求中提取和累积结果

时间:2016-03-04 11:50:14

标签: scala playframework playframework-2.0 future

我遇到了一个我现在无法解决的问题。我正在执行多个http请求,并且在每个响应中,它应该有Array[DTAnnotation]。我想将所有结果列表累加到一个(这不是问题)。我的问题是我无法从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]]

我如何解决这个问题?谢谢!

1 个答案:

答案 0 :(得分:1)

有许多错误可以避免这种情况发生。我添加了一个用您期望的类型编译的版本,如果您有问题,我会在评论中回答。

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)
      }
  }

问题:

  • 如果您希望列表,则必须将功能转换为列表 由理解返回
  • 未来回复的地图返回 另一个未来,这个值应该在Await
  • 中使用
  • 要确保所有分支中futureAnnotations的类型正确,该类型应该有效