2010-11-06 1 views
9

Ich versuche, JSON-Text mit dem Lift-Framework zu deserialisieren, und es scheint nicht, dass sie Seq-Eigenschaft unterstützen (obwohl List unterstützt wird). Als Beispiel ...Lift Framework kann JSON-Daten nicht deserialisieren

Einige JSON-Daten der Arbeitnehmer (mit Vor- und Zunamen) ...

{"employees":[{"fname":"Bob","lname":"Hope"},{"fname":"Bob","lname":"Smith"}]} 

Hier die Mitarbeiter Domain-Objekte:

case class Employee(fname: String, lname: String) { } 
case class Employees(employees: Seq[Employee]) { } 

Und hier ist meine JSON Deserialisierungscode ...

Wenn ich das Employees-Domäne-Objekt ändere, um List statt Seq zu verwenden, th de es funktioniert. Aber ich würde Seq gerne benutzen, wenn ich könnte.

Hier ist die Ausnahme, die ich sehe, wenn ich den obigen Code (mit Seq) ausführen: Gibt es etwas, was ich tun kann, um dies zu arbeiten? Danke für Ihre Hilfe!

net.liftweb.json.MappingException: unknown error 
    at net.liftweb.json.Extraction$.extract(Extraction.scala:43) 
    at net.liftweb.json.JsonAST$JValue.extract(JsonAST.scala:288) 
    at net.liftweb.json.Serialization$.read(Serialization.scala:50) 
    at EmployeeTest.deserialize(EmployeeTest.scala:20) 
    at EmployeeTest.test(EmployeeTest.scala:13) 
Caused by: java.lang.UnsupportedOperationException: tail of empty list 
    at scala.collection.immutable.Nil$.tail(List.scala:388) 
    at scala.collection.immutable.Nil$.tail(List.scala:383) 
    at net.liftweb.json.Meta$Constructor.bestMatching(Meta.scala:60) 
    at net.liftweb.json.Extraction$.findBestConstructor$1(Extraction.scala:187) 
    at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:192) 
    at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:222) 
    at net.liftweb.json.Extraction$.build$1(Extraction.scala:240) 
    at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:269) 
    at net.liftweb.json.Extraction$.build$1(Extraction.scala:242) 
    at net.liftweb.json.Extraction$$anonfun$4.apply(Extraction.scala:194) 
    at net.liftweb.json.Extraction$$anonfun$4.apply(Extraction.scala:194) 
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:206) 
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:206) 
    at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:61) 
    at scala.collection.immutable.List.foreach(List.scala:45) 
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:206) 
    at scala.collection.immutable.List.map(List.scala:45) 
    at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:194) 
    at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:222) 
    at net.liftweb.json.Extraction$.build$1(Extraction.scala:240) 
    at net.liftweb.json.Extraction$.extract(Extraction.scala:284) 
    at net.liftweb.json.Extraction$.extract0(Extraction.scala:172) 
    at net.liftweb.json.Extraction$.extract(Extraction.scala:40) 
    ... 33 more 
+0

ich in dieses Problem lief Auch ich bin froh, dass Sie diese Frage gestellt haben. Es wäre schön, wenn Lift-Json eine informativere Fehlermeldung ausgibt. –

Antwort

13

Seq wird in der Serialisierung nicht unterstützt, da es sich nicht um einen konkreten Typ handelt. Während der Deserialisierung gibt es keine Typinformation, die für eine konkrete Implementierung verwendet werden kann. Wir könnten zum Beispiel Liste als Standardimplementierung verwenden, aber dann die folgende Eigenschaft würde nicht mehr halten für alle Typen:

deserialize(serialize(x)) == x 

Dieser Sonderfall deserialisiert werden können wie folgt:

import net.liftweb.json._ 
import net.liftweb.json.JsonAST._ 

case class Employee(fname: String, lname: String) 
case class Employees(employees: Seq[Employee]) 

object Test extends Application { 
    implicit val formats = DefaultFormats 
    val s = """ {"employees":[{"fname":"Bob","lname":"Hope"},{"fname":"Bob","lname":"Smith"}]} """ 

    val json = JsonParser.parse(s) 
    val employees = Employees(for { 
    JArray(emps) <- json \ "employees" 
    emp <- emps 
    } yield emp.extract[Employee]) 

    println(employees) 
} 
+0

Danke für die klare Erklärung! – shj

+0

@shj, vielleicht kannst du das als richtige Antwort markieren. – Randin

Verwandte Themen