2014-11-04 1 views
1

Может кто-нибудь объяснить, почему происходит следующее?Scala Play JSON parser выдает ошибку при простом доступе к ключу

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

Большое спасибо

+1

'Json.toJson()' не * создает * объект. Он превращает объект в строку JSON. Я думаю, что вы хотите, это 'Json.parse()'. Когда вы будете разбирать строку JSON, это объект, и вы можете перейти к свойствам. –

ответ

1

Json.toJson делает свой аргумент как значение JSON с помощью неявно при условии Writes экземпляра. Если вы дадите ему строку, вы получите 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 экземпляров для собственных типов (здесь я использую игра "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

Повернувшись мой комментарий в ответ:

Json.toJson() не создает объект. Он превращает объект в строку JSON. Я думаю, что вы хотите Json.parse(). Как только у вас есть parse d строка JSON, это объект, и вы можете перейти к свойствам.

0

Большое спасибо вам обоим. Таким образом, следующее работает так, как ожидалось.

Скала> JSON.parse ("" "{" основной ":" тест "}" "") \ "основной" res137: play.api.libs.json.JsValue = "тест"

Я все еще хотел бы понять, что делает Json.toJson. В документах указано «Преобразовать поток A в поток JsValue». Может ли кто-нибудь указать, в каком контексте это можно использовать?

+0

'Json.toJson()' делает обратное 'Json.parse()'. Если parse преобразует строку JSON в объект, toJson преобразует объект в строку JSON. –

Смежные вопросы