Scala Play JSON解析器会在简单的键名访问时抛出错误

时间:2014-11-04 21:06:36

标签: json scala playframework

有人请解释为什么会发生以下情况吗?

scala> import play.api.libs.json._
scala> Json.toJson("""{"basic":"test"}""") // WORKS CORRECTLY
res134: play.api.libs.json.JsValue = "{\"basic\":\"test\"}"    

scala> Json.toJson(""" {"basic":"test"} """) \ "basic" // ??? HOW COME?
res131: play.api.libs.json.JsValue = JsUndefined('basic' is undefined on object: " {\"basic\":\"test\"} ")

非常感谢

3 个答案:

答案 0 :(得分:1)

Json.toJson使用隐式提供的Writes实例将其参数呈现为JSON值。如果你给它一个字符串,你会得到JsString(键入为JsValue)。你想要Json.parse来解析它的论点:

scala> Json.parse("""{"basic":"test"}""") \ "basic"
res0: play.api.libs.json.JsValue = "test"

正如所料。

要解决您的答案(顺便说一句,这应该是评论或新问题),如果您为toJson提供某种类型A的值,它会将其转换为JSON值,假设在Writes的范围内有A类型类的实例。例如,该库提供Writes[String]Writes[Int]等,因此您可以执行以下操作:

scala> Json.prettyPrint(Json.toJson(1))
res11: String = 1

scala> Json.prettyPrint(Json.toJson("a"))
res12: String = "a"

scala> Json.prettyPrint(Json.toJson(List("a", "b")))
res13: String = [ "a", "b" ]

您还可以为自己的类型创建Writes个实例(此处我正在使用Play的"JSON inception"):

case class Foo(i: Int, s: String)

implicit val fooWrites: Writes[Foo] = Json.writes[Foo]

然后:

scala> Json.prettyPrint(Json.toJson(Foo(123, "foo")))
res14: String = 
{
  "i" : 123,
  "s" : "foo"
}

使用类型类来管理编码和解码是基于反射的方法的替代方法,它有很多优点(但这超出了这个问题的范围)。

答案 1 :(得分:1)

将我的评论转化为答案:

Json.toJson()不会创建对象。它将对象转换为JSON字符串。我认为你想要的是Json.parse()。一旦您拥有parse个JSON字符串,它就是一个对象,您就可以访问这些属性。

答案 2 :(得分:0)

非常感谢你们两位。所以以下工作正如预期的那样。

阶> Json.parse(""" {"基本":"测试"}""")\& #34;碱性"   res137:play.api.libs.json.JsValue =" test"

我仍然想了解Json.toJson的作用。文档说明"将A流转换为JsValue"流。任何人都可以指出在什么情况下可以使用它?