我如何从Akka客户端HttpResponse解析json主体

mctunoxg  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(146)

我正在使用Akka的HTTP客户端库来请求一个json,并且我想使用Play Framework的play-json来解析这个json。在我得到Akka的HttpResponse之后,我不知道如何从响应主体中解析json,也不知道如何将json传递给onComplete指令中的另一个函数。相反,我得到了这个错误

overloaded method value parse with alternatives:
[error]   (input: Array[Byte])play.api.libs.json.JsValue <and>
[error]   (input: java.io.InputStream)play.api.libs.json.JsValue <and>
[error]   (input: String)play.api.libs.json.JsValue
[error]  cannot be applied to (scala.concurrent.Future[String])
[error]           val usefulInfo = Json.parse(data)
[error]                                 ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed

我现在尝试的是:

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.stream.ActorMaterializer
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.unmarshalling.Unmarshal
import play.api.libs.json._

object Main extends App {
    // Boilerplate code from Akka's documentation
    implicit val system = ActorSystem()
    implicit val materializer = ActorMaterializer()
    // needed for the future flatMap/onComplete in the end
    implicit val executionContext = system.dispatcher

    val request = HttpRequest(
        method = HttpMethods.GET,
        uri = "http://example.com/somedata.json"
    )
    var response: Future[HttpResponse] = Http().singleRequest(request)
    response.onComplete{
        case Success(res) => {
            val data = Unmarshal(res).to[String]
            val usefulInfo = Json.parse(data)
            println(usefulInfo)
        }
        case Failure(e)   => println(e)
    }
}

我的问题是:
1.如何在Future解析后,使用Play Framework的Json.parse()解析json?
1.在response Future解析之后,我如何在其他地方存储或使用这个json?我需要在Success的情况下做些什么吗?

vvppvyoh

vvppvyoh1#

主要的问题是Unmarshal返回Future,因此您需要处理Future中的数据以获得String值。
如果您希望保留结果而不仅仅是打印它,请对初始结果使用tranformWith而不是onComplete

val result = Http().singleRequest(request)
  .transformWith {
    case Success(res) =>
      val data = Unmarshal(res).to[String]

      data.map { d =>
        val usefulInfo = Json.parse(d)

        println(usefulInfo)

        usefulInfo
      }
    case Failure(e) =>
      println(e)

      Future.failed(e)
  }

请注意,如果您将打印保留到最后,则会更清晰:

val result = Http().singleRequest(request)
  .flatMap { res =>
    Unmarshal(res).to[String].map { data =>
      Json.parse(data)
    }
  }

result.onComplete {
  case Success(js) =>
    println(s"Success: $js")
  case Failure(e) =>
    println(s"Failure: $e")
}

相关问题