2013-10-26 18 views
6

Próbuję przetworzyć żądanie Ajax POST w Play Framework 2.1.3. Dane po to obiekt JSON i ma strukturę drzewa jak:Przeczytaj strukturę drzewa JSON w Scala Play Framework

{ id: "a", name: "myname", kids : [{ id: "a1", name : "kid1", kids: []}, {id: "a2", name: "kid2", kids: [{id: "aa1", name :"grandkid", kids: []}]}] 

chciałbym gniazdo dowolnie głęboko, że „dzieci”. Klasa chciałbym mieć na uwadze to tak (ja sobie sprawy recursiveness może być problematyczne):

case class Person { 
    id: String, 
    name: String, 
    kids: Array[Person] 
} 

Format chciałbym mieć na uwadze:

implicit val personFormat:Format[Person] = Json.format[Person] 

Play jest rzucanie błędy w moim formacie Napisałem:

niedopasowanie typu; znaleziono: controllers.Resources.Person required: Array [controllers.Resources.Person]

Mam świadomość, że Play ma strukturę Drzewa. Nie mogłem znaleźć przykładów/dokumentacji, jak powiązać to z odczytami JSON.

Każda pomoc jest bardzo ceniona dzięki

Odpowiedz

9

Musisz rekurencyjną val, coś takiego:

implicit val jsonReads: Reads[Person] = ((__ \ "id").read[String] and (__ \ "name").read[String] and (__ \ "kids").read[Seq[Person]])(apply _) 

(Zmieniłem typ Odbiór Array SEK, ponieważ jest bardziej ogólny i pozwala na zmianę implementacji bez wpływu downline kod.)

Używa składni udokumentowanej here.

+0

Dzięki Robin, próbuję włączyć twoją odpowiedź i dostaję błąd kompilacji "nie znaleziono: wartość jest ważna". Czy brakuje mi czegoś podstawowego? I czy "dzieci" w klasie "Osoba" muszą być "Sekwą [Person]", aby uzyskać odpowiedź? Dzięki! – Joost

+0

Och, myślę, że nie deklarujesz tego w obiekcie towarzyszącym. Więc po prostu zmień 'apply' na' Person'. Możesz zmienić to na 'Array', ale nie jestem pewien, czy Play może automatycznie czytać' Array's; dlatego zasugerowałem zmianę typu kolekcji używanej w 'Person' z' Array' na 'Seq'. Przepraszam, jeśli to nie było jasne. –

2

Jedyny sposób, że widzę to robocza jest przy użyciu JsArray lub Array [String] zamiast Array [osoby] w przypadku klasy Osoba. Incepcja makra JSON może generować tylko kody odczytu i zapisu dla prymitywów i list, map i tablic dla obiektów, dla których istnieje już niejawny kod odczytu i zapisu JSON. Zasadniczo nie możesz mieć klasy sprawy, która się odwołuje.

package models 

import play.api.libs.json._ 

case class Person(
    id : String, 
    name : String, 
    kids : JsArray 
) 

object Person extends ((String,String,JsArray) => Person) { 

    implicit val jsonFormat = Json.format[Person] 

} 
+1

To jednak nie jest dobry projekt; czyli odsłanianie reprezentacji drutu; co jeśli zdecydujesz się również akceptować XML? –

+1

Pytanie brzmiało, jak odczytać strukturę JSON, XML nie ma znaczenia. –

+1

Mówię o potencjalnej przyszłej decyzji dotyczącej projektu. Ale nawet niezależnie od tego nie powinieneś narażać reprezentacji drutu w swoich klasach przypadków - zmusza kod klienta do obaw o deserializację, której nie powinno się martwić. –

Powiązane problemy