2010-11-06 7 views
9

J'essaye de désérialiser le texte JSON en utilisant le framework Lift, et il ne semble pas qu'il supporte le trait Seq (bien que List soit supporté). A titre d'exemple ...Lift Framework ne peut pas désérialiser les données JSON

Certaines données JSON représentant les employés (avec nom et prénom) ...

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

est ici les objets de domaine-employés:

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

Et voici mon JSON code de désérialisation ...

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) 
    } 
} 

Si je change l'objet de domaine Employees pour utiliser List au lieu de Seq, ça marche. Mais j'aimerais vraiment utiliser Seq si je le pouvais.

Voici l'exception que je vois lorsque je lance le code ci-dessus (en utilisant Seq): Y at-il quelque chose que je puisse faire pour que cela fonctionne? Merci de votre aide!

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

je suis tombé sur ce problème aussi et je suis heureux que vous ayez posé cette question. Ce serait bien si lift-json a imprimé un message d'erreur plus informatif. –

Répondre

13

Seq n'est pas pris en charge dans la sérialisation car il ne s'agit pas d'un type concret. Lors de la désérialisation, aucune information de type ne peut être utilisée pour décider d'une implémentation concrète. Nous pourrions utiliser pour la liste d'instance comme une implémentation par défaut mais la propriété suivante ne tiendrions plus pour tous les types:

deserialize(serialize(x)) == x 

peut être désérialisée Ce cas particulier comme suit:

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

Merci pour l'explication claire! – shj

+0

@shj, peut-être que vous pouvez marquer ceci comme une réponse correcte alors. – Randin

Questions connexes