簡體   English   中英

如何解組 json 響應,使用 Akka HTTP 刪除不必要的字段

[英]How to unmarshall json response removing unnecessary fields using Akka HTTP

我是 Akka HTTP 的新手,我想從 JSON 響應中刪除不必要的字段,只取必要的字段。 例如,我使用這個端點來獲取響應,它包含一堆字段。 目前我只需要“名稱”和“版本”。 我想知道如何將其反序列化為僅包含“名稱”和“版本”的案例 class。 我對以下幾行進行了編碼以將響應作為字符串獲取。

import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.stream.scaladsl.{Flow, Sink, Source}
import akka.stream.{ActorMaterializer, OverflowStrategy}

import scala.concurrent.Future
import scala.concurrent.duration.DurationInt
import scala.language.postfixOps
import scala.util.{Failure, Success}

object SoftwareRegistry extends App {

  implicit val system = ActorSystem("NPMRegistry")
  implicit val materializer = ActorMaterializer()

  import system.dispatcher

  case class NPMPackage(name: String)

  // reading the packages
  val filename = "B:\\Scala\\NPMRegistry\\src\\main\\resources\\packages.txt"
  val bufferedSource = scala.io.Source.fromFile(filename)
  val listOfPackages: List[NPMPackage] = (for (line <- bufferedSource.getLines) yield {
    NPMPackage(line.trim)
  }).toList
  bufferedSource.close()

  // source
  val sourceList = Source(listOfPackages)

  // sink
  val sink = Sink.foreach[NPMPackage] { p =>
    // https request
    val responseFuture: Future[HttpResponse] =
      Http().singleRequest(HttpRequest(uri = s"https://registry.npmjs.org/${p.name}"))
    val x = responseFuture
      .flatMap(_.entity.toStrict(2 seconds))
      .map(_.data.utf8String)
    x.onComplete {
      case Success(res) => println(res)
      case Failure(_) => sys.error("Something went wrong")
    }
  }

  // flow to slow things down and streaming sink to time-delayed operations
  val bufferedFlow = Flow[NPMPackage]
    .buffer(10, overflowStrategy = OverflowStrategy.backpressure)
    .throttle(1, 3 seconds)

  sourceList.async
    .via(bufferedFlow).async
    .to(sink)
    .run()
}

它打印以下 output 在此處輸入圖像描述

要解析json您需要使用一些庫。 akka-http文檔中,他們使用spray-json 使用適當的akkaHttpVersion將以下依賴項添加到您的build.sbt中。

"com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion

現在您的數據需要序列化器和反序列化器。 我使用的是簡單的 model,根據需要進行更改。

trait Formatter extends DefaultJsonProtocol {

  implicit object jsonFormat extends JsonFormat[Versions] {
    override def read(json: JsValue): Versions = json match {
      case JsObject(fields) =>
        Versions(fields.keys.toList)
    }

    override def write(obj: Versions): JsValue = JsonParser(obj.toString)
  }

  implicit val formatterPackage: RootJsonFormat[Package] = jsonFormat2(Package)

  case class Package(name: String, versions: Versions)

  case class Versions(versions: List[String])
}

最后sink

 val sink = Sink.foreach[NPMPackage] { p =>
     // https request
     val responseFuture: Future[HttpResponse] =
       Http().singleRequest(HttpRequest(uri = s"https://registry.npmjs.org/${p.name}"))
     val packages = responseFuture
       .flatMap(
         _.entity
           .dataBytes
           .via(JsonFraming.objectScanner(Int.MaxValue))
           .map(_.utf8String)
           .map(_.parseJson.convertTo[Package])
           .toMat(Sink.seq)(Keep.right)
           .run()
       )

     packages.onComplete {
       case Success(res) => println(res)
       case Failure(_) => sys.error("Something went wrong")
     }
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM