我一直在努力通过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”)))))?
答案 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)
}
}