Lift Framework не может десериализовать данные JSON

Я пытаюсь десериализовать текст JSON с помощью платформы Lift, и похоже, что они не поддерживают черту Seq (хотя список поддерживается). Например...

Некоторые данные 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, тогда это сработает. Но я бы очень хотел использовать 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

person shj    schedule 06.11.2010    source источник
comment
Я тоже столкнулся с этой проблемой и рад, что вы задали этот вопрос. Было бы неплохо, если бы lift-json выводил более информативное сообщение об ошибке.   -  person Kipton Barros    schedule 26.07.2011


Ответы (1)


Seq не поддерживается в сериализации, так как это не конкретный тип. Во время десериализации нет информации о типе, которая может быть использована для принятия решения о конкретной реализации. Мы могли бы использовать, например, List как реализацию по умолчанию, но тогда следующее свойство больше не будет выполняться для всех типов:

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)
}
person Joni    schedule 06.11.2010