AkkaHTTP:从HttpEntity中获取内容 [英] AkkaHTTP: Getting content out of an HttpEntity

查看:890
本文介绍了AkkaHTTP:从HttpEntity中获取内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Scala中使用AkkaHTTP,试图与API进行交互,但是在通过某些API调用获取数据时遇到了一些麻烦。基本上,我有一个curl命令,该命令在终端中可用于对该特定API的任何有效API调用,但是在我的当前代码中,我仅获得响应足够小的调用的实际数据。

I'm working with AkkaHTTP in Scala, trying to interact with an API, but I'm having some trouble getting data with certain API calls. Basically, I have a curl command which works in my terminal for any valid API call to this certain API, but in my current code I only get the actual data for calls whose responses are small enough.

我的第一次尝试是使用sys.process._和!! curl(url)-X GET -H \授权:承载(身份验证令牌):(这是在我的终端上运行的命令)上的字符串的方法,但是由于以下原因导致scala错误并失败问题是解析标头;因此,在没有任何进展并意识到无论如何我都想使用AkkaHTTP之后,我放弃了这种方法,来到下面的代码,我从另一个stackoverflow帖子借来的格式。

My first attempt was using sys.process._ and the !! method on a string with "curl (url) -X GET -H \"Authorization: Bearer (auth token)\" (which is the command that works in my terminal), but that failed with an error in scala due to issues parsing the header; so after making no headway on that and realizing I wanted to use AkkaHTTP anyway, I abandoned that approach and came to the code below, whose format I borrowed from another stackoverflow 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调用;首先,在我的终端中返回一个327个字符的JSON字符串,然后返回一个blob,其中res.entity是HttpEntity.Strict(application / json,(与终端中的JSON Blob相同))。但是,尽管第二个调用在我的终端中返回了一个203,413个字符的JSON Blob(比第一个大得多),但是在scala中发送该请求会返回一个blob,其中res.entity只是HttpEntity.Chunked(application / json)。我想将有效负载拆分为多个数据包( Chunked是该情况的一个相当适用的名称),但是我似乎无法弄清楚如何从此处获取有效负载信息,我希望能有所帮助。

Now, I've tried this on two different API calls; the first, which in my terminal returns a JSON string with 327 characters, returns a blob, where res.entity is HttpEntity.Strict(application/json,(the same JSON blob as in the terminal)). However, while the second call returns in my terminal a JSON blob with 203,413 characters (much bigger than the first one), sending that request in scala returns a blob where res.entity is just HttpEntity.Chunked(application/json). I would presume the payload is split into multiple packets ("Chunked" being a fairly applicable name for that scenario), but I can't seem to figure out how to get the payload information from here, and I'd appreciate some help.

推荐答案

如果可以将整个实体加载到内存中,则可以调用 toStrict ResponseEntity :

If it's acceptable to load the entire entity into memory, you can call toStrict on the ResponseEntity:

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

您还可以使用内置的-in unmarshaller

You could also use a built-in unmarshaller:

import akka.http.scaladsl.unmarshalling.Unmarshal

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

这篇关于AkkaHTTP:从HttpEntity中获取内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆