2010-11-06 65 views
9

我试图使用Lift框架反序列化JSON文本,并且它没有出现它们支持Seq特征(尽管List支持)。作为一个例子...Lift Framework无法反序列化JSON数据

代表雇员(含姓和名)一些JSON数据...

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

这里的员工域的对象:

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

这是我的JSON反序列化代码...

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

如果我更改Employees域对象以使用List而不是Seq,th它的工作原理。但如果可以的话,我真的很想使用Seq。

下面是我运行上面的代码(使用Seq)时看到的异常:有什么我可以做到的吗?谢谢你的帮助!

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

我就遇到了这个问题也很高兴你问这个问题。如果lift-json打印出更多信息错误信息,那将会很好。 – 2011-07-26 00:19:12

回答

13

序列化中不支持Seq,因为它不是一个具体的类型。在反序列化过程中,没有可用于确定具体实现的类型信息。我们可以使用例如列表作为默认实现,但那么下面属性将不再适用于所有类型:

deserialize(serialize(x)) == x 

这种特殊情况下,可以反序列如下:

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

感谢您的明确解释! – shj 2010-11-07 05:04:22

+0

@shj,也许你可以标记这是一个正确的答案。 – Randin 2010-11-14 21:51:32