2010-11-06 10 views
9

Sto tentando di deserializzare il testo JSON utilizzando il framework Lift e non sembra che supportino il tratto Seq (sebbene sia supportato List). Per fare un esempio ...Lift Framework non può deserializzare i dati JSON

Alcuni dati JSON che rappresentano i lavoratori (con nome e cognome) ...

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

Ecco il dipendente domain-oggetti:

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

Ed ecco la mia JSON codice deserializzazione ...

class EmployeeTest { 

    @Test def test() { 
    val jsonText: String = .... 
    val e = deserialize(jsonText) 
    } 

    def deserialize(in: String): Employees = { 
    implicit val formats = net.liftweb.json.DefaultFormats 
    net.liftweb.json.Serialization.read[Employees](in) 
    } 
} 

se cambio l'oggetto di dominio ai dipendenti di utilizzare al posto di Lista Seq, th it funziona. Ma mi piacerebbe davvero usare Seq se potessi.

Ecco l'eccezione che vedo quando eseguo il codice precedente (utilizzando Seq): C'è qualcosa che posso fare per farlo funzionare? Grazie per l'aiuto!

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

mi sono imbattuto in questo problema e sono contento che tu abbia fatto questa domanda. Sarebbe bello se lift-json avesse stampato un messaggio di errore più informativo. –

risposta

13

Seq non è supportato in serializzazione perché non è un tipo concreto. Durante la deserializzazione non ci sono informazioni di tipo che possono essere utilizzate per decidere sull'implementazione concreta. Potremmo usare per esempio List come implementazione di default, ma allora quanto segue bene non terrebbe per tutti i tipi:

deserialize(serialize(x)) == x 

Questo caso specifico può essere deserializzato come segue:

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

Grazie per la chiara spiegazione! – shj

+0

@shj, forse puoi contrassegnarlo come una risposta corretta. – Randin

Problemi correlati