2017-02-18 2 views
0

So habe ich eine Struktur in json wie folgt aussehen:Play-Framework lesen von json Liste

{ 
    "lst": [ 
     {"name": "foo"}, 
     {"name": "bar"} 
    ] 
} 

ich die härteste Zeit, die diese zu einer Liste von Fallklassen zu konvertieren. Ich bin sicher, ich bin etwas fehlt ganz offensichtlich ...

Ich habe dies versucht:

case class Person(name: String) 
implicit val personReads: Reads[Email] = (__ \\ "name").read[String](Person) 

// endpoint 
def person = Action { request => 
    val person = request.body.asJson.get.as[Seq[Person]] 
} 

, die nicht da read nicht kompiliert kehrt nicht ein FunctionBuilder was bedeutet, kann ich nicht gelten der Weg zum Person

einen neuen Parameter nicht kompiliert (die json und Fallklasse ändert sich entsprechend) Hinzufügen:

case class Person(name: String, age: String) 
implicit val personReads: Reads[Email] = (
    (__ \\ "name").read[String]) and 
    (__ \\ "age").read[Int](Person) 

aber thr ows eine Ausnahme Execution exception[[JsResultException: JsResultException(errors:List((,List(ValidationError(List(error.expected.jsarray),WrappedArray())))))]] angeblich, weil es eine Liste erwartet. So

Ich versuchte dies und fügte hinzu:

implicit val personsReads: Reads[Seq[Person]] = (__ \ "lst").read[Seq[Person]] 

, die dann ein NullPointer wirft.

Am Ende möchte ich nur eine Seq[Person]. Kann mir jemand in die richtige Richtung zeigen, ich bin völlig verloren, was ich hier tun soll ...

Antwort

2

Sie können Folgendes tun, anstatt explizit lesen und schreiben.

import play.api.json.Json 

case class Person(name: String) 
object Person { 
    implicit val personFormat = Json.format[Person] 
} 

case class Persons(lst: List[Person]) 

object Persons { 
implicit val personsFormat = Json.format[Persons] 
} 

Nun nehmen Sie die JSON-String jsonStr

Json.parse(jsonStr).validate[Persons] match { 
case JsSuccess(persons, _) => println(persons) 
case JsError(_) => println("parsing failed") 
} 

Scala REPL

scala> import play.api.libs.json._ 
import play.api.libs.json._ 

scala> val str = """{ 
    |  "lst": [ 
    |   {"name": "foo"}, 
    |   {"name": "bar"} 
    |  ] 
    | }""".stripMargin 
str: String = 
{ 
    "lst": [ 
     {"name": "foo"}, 
     {"name": "bar"} 
    ] 
} 

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

case class Person(name: String) 
object Person { 
    implicit val personFormat = Json.format[Person] 
} 

case class Persons(lst: List[Person]) 

object Persons { 
implicit val personsFormat = Json.format[Persons] 
} 

// Exiting paste mode, now interpreting. 

defined class Person 
defined object Person 
defined class Persons 
defined object Persons 

scala> val jsonStr = str 
jsonStr: String = 
{ 
    "lst": [ 
     {"name": "foo"}, 
     {"name": "bar"} 
    ] 
} 

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

Json.parse(jsonStr).validate[Persons] match { 
case JsSuccess(persons, _) => println(persons) 
case JsError(_) => println("parsing failed") 
} 

// Exiting paste mode, now interpreting. 

Persons(List(Person(foo), Person(bar))) 

Jetzt können sagen, wenn Sie Ihre Person Fall Klasse ändern und age Feld hinzufügen.

case class Person(name: String, age: Int) 

object Person { 
implicit val personFormat = Json.format[Person] 
} 

Stellen Sie sicher, dass der JSON, den Sie analysieren möchten, sowohl den Namen als auch das Alter enthält. Wenn Sie nur Namen haben, erhalten Sie einen Parsing-Fehler.

+1

Das ist großartig, viel sauberer als jedes Beispiel in der Play Framework-Dokumentation. Klappt wunderbar! – Tim