2010-11-06 9 views
9

Estoy intentando deserializar el texto JSON utilizando Lift Framework, y no parece que admitan el rasgo Seq (aunque List es compatible). A modo de ejemplo ...Lift Framework no puede deserializar los datos JSON

Algunos datos JSON representan a los empleados (con nombre y apellido) ...

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

Aquí es el dominio de los objetos empleados:

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

Y aquí es mi JSON código deserialización ...

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 cambio el objeto de dominio a los empleados a utilizar la lista en lugar de Sec, TH en que funciona Pero realmente me gustaría usar Seq si pudiera.

Esta es la excepción que veo cuando ejecuto el código anterior (usando Seq): ¿Hay algo que pueda hacer para que esto funcione? ¡Gracias por tu ayuda!

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

me encontré con este problema también y me alegra que hayas hecho esta pregunta. Sería bueno si lift-json imprimiera un mensaje de error más informativo. –

Respuesta

13

Sec no es compatible con la serialización porque no es un tipo de hormigón. Durante la deserialización no hay información de tipo que pueda usarse para decidir sobre la implementación concreta. Podríamos utilizar para la lista de instancias como aplicación por defecto, pero luego la siguiente propiedad ya no aguantaría todos los tipos:

deserialize(serialize(x)) == x 

este caso específico se puede deserializar de la siguiente manera:

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

¡Gracias por la explicación clara! – shj

+0

@shj, quizás usted pueda marcar esto como una respuesta correcta. – Randin

Cuestiones relacionadas