[FIXED] Zuordnen einer Zeichenfolge zu Fallklassen mithilfe von Scala Play

Ausgabe

Mit der Scala-Spielbibliothek versuche ich, die Zeichenfolge zu analysieren:

  var str = "{\"payload\": \"[{\\\"test\\\":\\\"123\\\",\\\"tester\\\":\\\"456\\\"}," +
    "{\\\"test1\\\":\\\"1234\\\",\\\"tester2\\\":\\\"4567\\\"}]\"}";

in eine Liste von PayloadKlassen mit dem folgenden Code:

import play.api.libs.json._

object TestParse extends App {
  
  case class Payload(test : String , tester : String)
  object Payload {
    implicit val jsonFormat: Format[Payload] = Json.format[Payload]
  }

  var str = "{\"payload\": \"[{\\\"test\\\":\\\"123\\\",\\\"tester\\\":\\\"456\\\"}," +
    "{\\\"test1\\\":\\\"1234\\\",\\\"tester2\\\":\\\"4567\\\"}]\"}";

  println((Json.parse(str) \ "payload").as[List[Payload]])

}

build.sbt :

name := "akka-streams"

version := "0.1"

scalaVersion := "2.12.8"

lazy val akkaVersion = "2.5.19"
lazy val scalaTestVersion = "3.0.5"

libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-stream" % akkaVersion,
  "com.typesafe.akka" %% "akka-stream-testkit" % akkaVersion,
  "com.typesafe.akka" %% "akka-testkit" % akkaVersion,
  "org.scalatest" %% "scalatest" % scalaTestVersion
)

// https://mvnrepository.com/artifact/com.typesafe.play/play-json
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.10.0-RC6"

Es schlägt fehl mit Ausnahme:

Exception in thread "main" play.api.libs.json.JsResultException: JsResultException(errors:List((,List(JsonValidationError(List("" is not an object),WrappedArray())))))

Ist die Fallklassenstruktur falsch?

Ich habe den Code aktualisiert auf:

import play.api.libs.json._

object TestParse extends App {

  import TestParse.Payload.jsonFormat
  object Payload {
    implicit val jsonFormat: Format[RootInterface] = Json.format[RootInterface]
  }
  case class Payload (
                       test: Option[String],
                       tester: Option[String]
                     )

  case class RootInterface (
                             payload: List[Payload]
                           )

  val str = """{"payload": [{"test":"123","tester":"456"},{"test1":"1234","tester2":"4567"}]}"""

  println(Json.parse(str).as[RootInterface])

}

was einen Fehler zurückgibt:

Keine Instanz von play.api.libs.json.Format ist für scala.collection.immutable.List[TestParse.Payload] im impliziten Bereich verfügbar (Hinweis: Wenn in derselben Datei deklariert, stellen Sie sicher, dass es vorher deklariert ist) implizites val jsonFormat : Format[RootInterface] = Json.format[RootInterface]

Lösung

Dies führt die Aufgabe aus, aber es gibt sauberere Lösungen:

import akka.actor.ActorSystem
import akka.stream.scaladsl.{Flow, Sink, Source}
import org.scalatest.Assertions._
import spray.json.{JsObject, JsonParser}

import scala.concurrent.Await
import scala.concurrent.duration.DurationInt

object TestStream extends App {
  implicit val actorSystem = ActorSystem()
  val mapperFlow = Flow[JsObject].map(x => {
    x.fields.get("payload").get.toString().replace("{", "")
      .replace("}", "")
      .replace("[", "")
      .replace("]", "")
      .replace("\"", "")
      .replace("\\", "")
      .split(":").map(m => m.split(","))
      .toList
      .flatten
      .grouped(4)
      .map(m => Test(m(1), m(3).toDouble))
      .toList
  })

  val str = """{"payload": [{"test":"123","tester":"456"},{"test":"1234","tester":"4567"}]}"""
  case class Test(test: String, tester: Double)

val graph = Source.repeat(JsonParser(str).asJsObject())
  .take(3)
  .via(mapperFlow)
  .mapConcat(identity)
  .runWith(Sink.seq)

  val result = Await.result(graph, 3.seconds)

  println(result)
  assert(result.length == 6)
  assert(result(0).test == "123")
  assert(result(0).tester == 456 )
  assert(result(1).test == "1234")
  assert(result(1).tester == 4567 )
  assert(result(2).test == "123")
  assert(result(2).tester == 456 )
  assert(result(3).test == "1234")
  assert(result(3).tester == 4567 )

}

Alternative, ioiomatische Scala-Antworten sind willkommen.


Beantwortet von –
blauer Himmel


Antwort geprüft von –
Mildred Charles (FixError Admin)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like