【问题标题】:Extracting and accumulate result from multiple HTTP request从多个 HTTP 请求中提取和累积结果
【发布时间】:2016-06-18 03:29:05
【问题描述】:

我遇到了这些天无法解决的问题。我正在执行多个 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]]

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

【问题讨论】:

    标签: scala playframework playframework-2.0 future


    【解决方案1】:

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

    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 理解返回
    • 未来响应地图返回 另一个未来,这个值应该在等待中使用
    • 为了确保 futureAnnotations 的类型在所有分支中都是正确的,该类型应该是有效的

    【讨论】:

    • 像魅力一样工作!也感谢您的时间和 cmets
    • 不客气。一旦你让它工作,你可以改进它一点。避免等待并阅读有关组成期货的信息。 Daniel Westheide 的教程非常好。这是关于期货的章节danielwestheide.com/blog/2013/01/09/…
    • 您是否建议使用flatMap 而不是map
    • 不,我的评论更多是关于学习处理期货。特别避免使用Await,除非没有其他办法。
    猜你喜欢
    • 2019-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-18
    • 2018-12-15
    • 2020-02-13
    相关资源
    最近更新 更多