Akka HTTP:从 HttpEntity 获取内容

AkkaHTTP: Getting content out of an HttpEntity

我正在 Scala 中使用 AkkaHTTP,尝试与 API 交互,但我在通过某些 API 调用获取数据时遇到了一些问题。基本上,我有一个 curl 命令在我的终端中工作,用于对这个特定 API 的任何有效 API 调用,但在我当前的代码中,我只获得响应足够小的调用的实际数据。

我的第一次尝试是使用 sys.process._ 和 !!带有 "curl (url) -X GET -H \"Authorization: Bearer (auth token)\" 的字符串上的方法(这是在我的终端中运行的命令),但由于解析 header 的问题导致 scala 失败并出现错误;所以在这方面没有取得任何进展并意识到我无论如何都想使用 AkkaHTTP 之后,我放弃了这种方法并使用下面的代码,我从另一个 Whosebug post.

借用了它的格式
implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
implicit val executionContext = system.dispatcher

val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(
  uri = "(url)").withHeaders(
  RawHeader("Authorization", "Bearer (auth token)")
))


responseFuture
  .onComplete {
    case Success(res) => println(res)
    case Failure(_)   => "failure"
  }

现在,我已经在两个不同的 API 调用中尝试过;第一个,在我的终端中 returns 一个包含 327 个字符的 JSON 字符串,returns 一个 blob,其中 res.entity 是 HttpEntity.Strict(application/json, (与终端中的 JSON blob 相同)。但是,虽然我的终端中的第二次调用 returns 是一个包含 203,413 个字符的 JSON blob(比第一个大得多),但在 scala returns 中发送了一个 blob,其中 res.entity 只是 HttpEntity.Chunked(application/json)。我假设有效载荷被分成多个数据包("Chunked" 是该场景的一个相当适用的名称),但我似乎无法弄清楚如何从这里获取有效载荷信息,我会很感激一些帮助。

如果可以接受将整个实体加载到内存中,您可以在 ResponseEntity:

上调用 toStrict
import scala.concurrent.Future
import scala.concurrent.duration._

val entityFut: Future[String] =
  responseFuture.flatMap(_.entity.toStrict(5 seconds).map(_.data.utf8String))

entityFut.onComplete {
  case Success(body) =>
    println(body)
  case Failure(_) =>
    println("failure")
}

您也可以使用内置 unmarshaller:

import akka.http.scaladsl.unmarshalling.Unmarshal

val entityFut: Future[String] =
  responseFuture.flatMap(resp => Unmarshal(resp.entity).to[String])