我试图将akka HttpResponse编组如下:
{
"code": 200,
"headers": [],
"body": "{\"data\": \"Yes!\"}"
}如果我为这个实例编写了一个Argonaut EncodeJson,它可能如下所示:
implicit def httpResponseEncodeJson: EncodeJson[HttpResponse] =
EncodeJson(
(res: HttpResponse) ⇒ {
("code" := res._1.value) ->:
("headers" := res._2.toList) ->:
("body" := res._3) ->: jEmptyObject
}
)我已经设法将头封封为json。唯一的问题是身体,即ResponseEntity。因为它是一个akka流,所以如果我使用.toStrict,它只能返回一个未来。
有人能指导我怎么整理它吗?
发布于 2017-01-19 14:32:49
如果可能,我将将封送值保留为Future,以保持实体提取的异步性。
我一开始就有这样的想法
case class StrictHttpResponse(code: String, headers: List[HttpHeader], body: String)
def toStrictResponse(response: HttpResponse): Future[StrictHttpResponse] = response.entity.dataBytes.runFold(ByteString(""))(_ ++ _).map { bs =>
StrictHttpResponse(response.status.value, response.headers.toList, bs.utf8String)
}
implicit def httpResponseEncodeJson: EncodeJson[StrictHttpResponse] =
EncodeJson(
(res: StrictHttpResponse) ⇒ {
("code" := res.code) ->:
("headers" := res.headers) ->:
("body" := res.body) ->: jEmptyObject
}
)
def encodeResponse(response: HttpResponse): Future[Json] = toStrictResponse(response).map(_.jencode)然后--例如--通过提供回调来处理encodeResponse的结果。
发布于 2017-01-20 15:17:50
我最终使用了这个:
implicit def httpResponseListMarshal: ToEntityMarshaller[List[HttpResponse]] =
Marshaller { implicit ec ⇒ (responses: List[HttpResponse]) ⇒
// Sink for folding Source of ByteString into 1 single huge ByteString
val sink = Sink.fold[ByteString, ByteString](ByteString.empty)(_ ++ _)
// A List of Future Json obtained by folding Source[ByteString]
// and mapping appropriately
val listFuture: List[Future[Json]] = for {
res ← responses
} yield for {
byteString ← res._3.dataBytes runWith sink
string = byteString.utf8String
} yield ("code" := res._1.intValue) ->:
("headers" := res._2.toList) ->:
("body" := string) ->: jEmptyObject
// Convert List[Future[Json]] to Future[List[Json]]
val futureList: Future[List[Json]] = Future.sequence(listFuture)
// ToEntityMarshaller is essentially a Future[List[Marshalling[RequestEntity]]]
for {
list ← futureList
json = jArray(list).nospaces
} yield List(
Marshalling.Opaque[RequestEntity](() ⇒
HttpEntity(`application/json`, json)
).asInstanceOf[Marshalling[RequestEntity]]
)
}完整的代码和示例用法可以在这里找到:https://github.com/yashsriv/akka-http-batch-api/blob/argonaut/src/main/scala/org.yashsriv/json/Batch.scala
https://stackoverflow.com/questions/40959541
复制相似问题