2010-11-06 14 views
9

Próbuję deserializować tekst JSON przy użyciu podnośnika framework i nie wydaje się, że obsługuje on cechy Seq (chociaż List jest obsługiwany). Jako przykład ...Podnośnik Framework nie może deserializować danych JSON

niektórych danych JSON reprezentujących pracowników (z imienia i nazwiska) ...

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

oto domena obiekty Pracownik:

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

A oto mój JSON kod deserializacji ...

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

Jeśli zmienię obiekt domeny Pracownicy, aby użyć listy zamiast wartości Seq, en to działa. Ale naprawdę chciałbym użyć Seq, gdybym mógł.

Oto wyjątek, który widzę po uruchomieniu powyższego kodu (przy użyciu Seq): Czy jest coś, co mogę zrobić, aby to działało? Dzięki za pomoc!

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

wpadłem na ten problem też i cieszę się, że zadałeś to pytanie. Byłoby miło, gdyby lift-json wydrukował bardziej informacyjny komunikat o błędzie. –

Odpowiedz

13

Seq nie jest obsługiwany podczas serializacji, ponieważ nie jest konkretny. Podczas deserializacji nie ma informacji o typie, które można wykorzystać do decydowania o konkretnej implementacji. Możemy użyć na przykład listy jako domyślną implementację ale wtedy następującą właściwość nie będzie już dłużej dla wszystkich typów:

deserialize(serialize(x)) == x 

Ten przypadek może rozszeregować następująco:

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

Dzięki za jasne wyjaśnienie! – shj

+0

@shj, może wtedy możesz oznaczyć tę poprawną odpowiedź. – Randin

Powiązane problemy