使用lift-json使用Map [String,Any]属性反序列化案例类

时间:2011-02-19 14:26:50

标签: json serialization scala lift

我一直在努力通过lift-json做一些简单的事情:将地图序列化为JSON。

我知道,我知道 - “Root对象还不能是List或Map” - 但我现在愿意将它包装在一个案例类中,但我仍然无法使其工作。感谢一些堆栈溢出帮助,我有序列化工作,但我无法从字符串反序列化。我收到的错误如“ _ 没有可用价值”和“没有关于类型的信息。”

网络上还有其他较旧的帖子表明类型提示是答案,但这只会导致不同的错误,例如“不知道如何反序列化 _ _。”

对于Scala 2.8.0和Lift 2.2:

import net.liftweb.json._
import net.liftweb.json.Serialization.{read, write}

case class MapWrap(data: Map[String, Any])

object Scaffold {
    def main(args: Array[String]) {

        implicit val formats = Serialization.formats(NoTypeHints)
        //implicit val formats = Serialization.formats(ShortTypeHints(List(classOf[MapWrap])))
        //implicit val formats = Serialization.formats(FullTypeHints(List(classOf[MapWrap])))

        val ser = write(new MapWrap(Map[String,Any]("key" -> "value")))
        println("JSON: " + ser)
        println(read[MapWrap](ser))

    }
}

println(read[MapWrap](ser))会导致投诉“net.liftweb.json.MappingException:数据没有可用值。”

如何反序列化此case类包装器(或实现我的最终目标:read(write(“key” - >“value”)))))?

2 个答案:

答案 0 :(得分:2)

如果您将Map更改为Map [String,String],则此示例有效。然后序列化程序知道您期望String值。如果您的Map值是多态的,则需要输入提示。喜欢Map [String,Animal];狗延伸动物; Cat扩展了Animal等。现在,Animal类型需要一个类型提示。它将“jsonClass”字段添加到JSON,用于决定具体的目标类型。

如果您可以升级到2.3-M1,那么您不再需要包装地图,但可以直接序列化地图:

http://www.scala-tools.org/repo-releases/net/liftweb/lift-json_2.8.1/2.3-M1/

答案 1 :(得分:2)

或者,您可以使用case case class params作为JObject并使用.values方法:

import org.junit.{Test, Assert, Before}
import org.junit.Assert._
import net.liftweb.json._

case class Element(title:String, params:JObject)
@Test
class JsonParserTest{
 implicit val formats = Serialization.formats(NoTypeHints)

 @Test
  def testLiftMapToAny{
    val result = parse("""{"title":"foobar","params":{"one":1,"two":2, "other": "give"}}""").extract[Element]

    assertEquals("foobar", result.title)
    assertEquals(Map("one" -> 1, "two" -> 2, "other" -> "give"), result.params.values)
  }
}