akka HttpResponse将body读取为String scala

tg4*_*g44 29 scala akka akka-http

所以我有一个带有这个签名的函数(akka.http.model.HttpResponse):

def apply(query: Seq[(String, String)], accept: String): HttpResponse
Run Code Online (Sandbox Code Playgroud)

我只是在测试中得到一个值:

val resp = TagAPI(Seq.empty[(String, String)], api.acceptHeader)
Run Code Online (Sandbox Code Playgroud)

我想在测试中检查它的身体,例如:

resp.entity.asString == "tags"
Run Code Online (Sandbox Code Playgroud)

我的问题是如何将响应体作为字符串?

小智 26

import akka.http.scaladsl.unmarshalling.Unmarshal

implicit val system = ActorSystem("System")  
implicit val materializer = ActorFlowMaterializer() 

val responseAsString: Future[String] = Unmarshal(entity).to[String]
Run Code Online (Sandbox Code Playgroud)


Kon*_*ski 23

由于Akka Http是基于流的,因此实体也是流式传输.如果您确实需要一次完整的字符串,可以将传入的请求转换为Strict一个:

这是通过使用toStrict(timeout: FiniteDuration)(mat: Materializer)API在给定时间限制内将请求收集到严格实体中完成的(这很重要,因为您不希望"尝试永远收集实体",以防传入请求实际上永远不会结束):

import akka.stream.ActorFlowMaterializer
import akka.actor.ActorSystem

implicit val system = ActorSystem("Sys") // your actor system, only 1 per app
implicit val materializer = ActorFlowMaterializer() // you must provide a materializer

import system.dispatcher
import scala.concurrent.duration._
val timeout = 300.millis

val bs: Future[ByteString] = entity.toStrict(timeout).map { _.data }
val s: Future[String] = bs.map(_.utf8String) // if you indeed need a `String`
Run Code Online (Sandbox Code Playgroud)


小智 7

你也可以尝试这个.

responseObject.entity.dataBytes.runFold(ByteString(""))(_ ++ _).map(_.utf8String) map println
Run Code Online (Sandbox Code Playgroud)


小智 5

Unmarshaller.stringUnmarshaller(someHttpEntity)
Run Code Online (Sandbox Code Playgroud)

像魅力一样工作,也需要隐式物化器


Ale*_*rov 5

这是string从请求正文中提取的简单指令

def withString(): Directive1[String] = {
  extractStrictEntity(3.seconds).flatMap { entity =>
    provide(entity.data.utf8String)
  }
}
Run Code Online (Sandbox Code Playgroud)