Как я могу создать и проанализировать строку JSON в Scala / Lift
Вопрос
Я пытаюсь использовать JSON для отправки данных между браузером и моим приложением.
Я пытаюсь использовать Lift 1.0 для создания и анализа строк JSON, но по какой-то причине я не могу проанализировать JSON, который я только что создал:
scala>import scala.util.parsing.json.JSON._
import scala.util.parsing.json.JSON._
scala> import net.liftweb.http.js._
import net.liftweb.http.js._
scala> import net.liftweb.http.js.JE._
import net.liftweb.http.js.JE._
scala> val json = JsObj(("foo", 4), ("bar", "baz")).toJsCmd
json: String = {'foo': 4, 'bar': 'baz'}
scala> parseFull(json)
res3: Option[Any] = None
Как мне программно создать допустимое JSON-сообщение в Scala / Lift, которое также можно повторно проанализировать?
Решение
Вы используете Lift 1.0 JsCmd
, который выдает JSON со строками, заключенными в одинарные кавычки, и пытается проанализировать его с помощью анализатора scala, который поддерживает только строки, заключенные в двойные кавычки.
Важно понимать, что существует несколько определений для JSON.
Допустимы ли строки, заключенные в одинарные кавычки, в JSON?
- Они находятся в соответствии с ECMAScript 5 - е Изд
- Они не соответствуют оригиналу Крокфорда RFC 4627
Lift и Scala предоставляют множество способов синтаксического анализа JSON, иногда с различным поведением в разных версиях.
Строки, принимаемые этими анализаторами, не эквивалентны.
Вот несколько комментариев и примеров различных методов создания и синтаксического анализа строк JSON.
Создание JSON с помощью лифт-json библиотека DSL
- Рекомендуемые
- Несмотря на свое название, это отдельный проект, не имеющий зависимостей от остальной части Lift
пример:
scala> import net.liftweb.json.JsonAST
import net.liftweb.json.JsonAST
scala> import net.liftweb.json.JsonDSL._
import net.liftweb.json.JsonDSL._
scala> import net.liftweb.json.Printer._
import net.liftweb.json.Printer._
scala> val json1 = ("foo" -> 4) ~ ("bar" -> "baz")
json1: net.liftweb.json.JsonAST.JObject = JObject(List(JField(foo,JInt(4)), JField(bar,JString(baz))))
scala> compact(JsonAST.render(json1))
res0: String = {"foo":4,"bar":"baz"}
scala> val json2 = List(1,2,3)
json2: List[Int] = List(1, 2, 3)
scala> compact(JsonAST.render(json2))
res1: String = [1,2,3]
scala> val json3 = ("foo", 4) ~ ("bar", List(1,2,3))
json3: net.liftweb.json.JsonAST.JObject = JObject(List(JField(foo,JInt(4)), JField(bar,JArray(List(JInt(1), JInt(2), JInt(3))))))
scala> compact(JsonAST.render(json3))
res2: String = {"foo":4,"bar":[1,2,3]}
Синтаксический анализ JSON с помощью лифт-json библиотека
- Рекомендуемые
- Обеспечивает неявное отображение в /из case-классов scala
- Case-классы, определенные в консоли, в данный момент не поддерживаются (вызовет
com.thoughtworks.paranamer.ParameterNamesNotFoundException: Unable to get class bytes
) - В приведенном ниже примере используется
Публичный идентификатор
, уже существующий case-класс scala, чтобы он работал на консоли scala.
пример:
scala> import scala.xml.dtd.PublicID
import scala.xml.dtd.PublicID
scala> import net.liftweb.json._
import net.liftweb.json._
scala> import net.liftweb.json.JsonAST._
import net.liftweb.json.JsonAST._
scala> import net.liftweb.json.JsonDSL._
import net.liftweb.json.JsonDSL._
scala> implicit val formats = DefaultFormats
formats: net.liftweb.json.DefaultFormats.type = net.liftweb.json.DefaultFormats$@7fa27edd
scala> val jsonAst = ("publicId1" -> "idString") ~ ("systemId" -> "systemIdStr")
jsonAst: net.liftweb.json.JsonAST.JObject = JObject(List(JField(publicId,JString(idString)), JField(systemId,JString(systemIdStr))))
scala> jsonAst.extract[PublicID]
res0: scala.xml.dtd.PublicID = PUBLIC "idString" "systemIdStr"
Синтаксический анализ JSON в scala 2.7.7 и 2.8.1
- Не рекомендуется ... "На самом деле больше не поддерживается"
- Анализатор Scala 2.7.7 не будет анализировать JSON, заключенный в одинарные кавычки
- Этот метод синтаксического анализа, используемый в вопросе
пример:
scala>import scala.util.parsing.json.JSON._
import scala.util.parsing.json.JSON._
scala> parseFull("{\"foo\" : 4 }")
res1: Option[Any] = Some(Map(foo -> 4.0))
scala> parseFull("[ 1,2,3 ]")
res2: Option[Any] = Some(List(1.0, 2.0, 3.0))
scala> parseFull("{'foo' : 4 }")
res3: Option[Any] = None
Синтаксический анализ JSON в Lift 2.0 и 2.2 с помощью утилита.JsonParser
- Нейтральная Рекомендация
- Util.JsonParser от Lift будет анализировать строки JSON, заключенные в одинарные или двойные кавычки:
пример:
scala> import net.liftweb.util.JSONParser._
import net.liftweb.util.JSONParser._
scala> parse("{\"foo\" : 4 }")
res1: net.liftweb.common.Box[Any] = Full(Map(foo -> 4.0))
scala> parse("[ 1,2,3 ]")
res2: net.liftweb.common.Box[Any] = Full(List(1.0, 2.0, 3.0))
scala> parse("{'foo' : 4}")
res3: net.liftweb.common.Box[Any] = Full(Map(foo -> 4.0))
Синтаксический анализ JSON в Lift 2.0 и 2.2 с помощью json.JsonParser
- Нейтральная Рекомендация
- Json от Lift.JsonParser не будет анализировать строки JSON, заключенные в одинарные кавычки:
пример:
scala> import net.liftweb.json._
import net.liftweb.json._
scala> import net.liftweb.json.JsonParser._
import net.liftweb.json.JsonParser._
scala> parse("{\"foo\" : 4 }")
res1: net.liftweb.json.JsonAST.JValue = JObject(List(JField(foo,JInt(4))))
scala> parse("[ 1,2,3 ]")
res2: net.liftweb.json.JsonAST.JValue = JArray(List(JInt(1), JInt(2), JInt(3)))
scala> parse("{'foo' : 4}")
net.liftweb.json.JsonParser$ParseException: unknown token '
Near: {'foo' : 4}
at net.liftweb.json.JsonParser$Parser.fail(JsonParser.scala:216)
at net.liftweb.json.JsonParser$Parser.nextToken(JsonParser.scala:308)
at net.liftweb.json.JsonParser$$anonfun$1.apply(JsonParser.scala:172)
at net.liftweb.json.JsonParser$$anonfun$1.apply(JsonParser.scala:129)
at net.liftweb.json.JsonParse...
Создание JSON с помощью Lift 1.0 JsCmd
- Не рекомендуется - вывод недопустим для всех анализаторов JSON
- Обратите внимание на одинарные кавычки вокруг строк:
пример:
scala> import net.liftweb.http.js._
import net.liftweb.http.js._
scala> import net.liftweb.http.js.JE._
import net.liftweb.http.js.JE._
scala> JsObj(("foo", 4), ("bar", "baz")).toJsCmd
res0: String = {'foo': 4, 'bar': 'baz'}
scala> JsArray(1,2,3).toJsCmd
res1: String =
[1, 2, 3]
scala> JsObj(("foo", 4), ("bar", JsArray(1,2,3))).toJsCmd
res2: String =
{'foo': 4, 'bar': [1, 2, 3]
}
Создание JSON с помощью Lift 2.0 JsCmd
- Нейтральная Рекомендация
- Обратите внимание на двойные кавычки вокруг строк:
пример:
scala> import net.liftweb.http.js._
import net.liftweb.http.js._
scala> import net.liftweb.http.js.JE._
import net.liftweb.http.js.JE._
scala> JsObj(("foo", 4), ("bar", "baz")).toJsCmd
res0: String = {"foo": 4, "bar": "baz"}
scala> JsArray(1,2,3).toJsCmd
res1: String =
[1, 2, 3]
scala> JsObj(("foo", 4), ("bar", JsArray(1,2,3))).toJsCmd
res3: String =
{"foo": 4, "bar": [1, 2, 3]
}
Создание JSON в scala (протестировано с 2.10)
- "На самом деле больше не поддерживается", но это работает, и это есть.
пример:
scala> import scala.util.parsing.json._
import scala.util.parsing.json._
scala> JSONObject (Map ("foo" -> 4, "bar" -> JSONArray (1 :: 2 :: 3 :: Nil))) .toString()
res0: String = {"foo" : 4, "bar" : [1, 2, 3]}
Другие советы
Взгляните на Цирцея.Им действительно приятно пользоваться, и в нем используются некоторые новые инструменты от Бесформенный и Кошки.Кроме того, вы можете использовать его из Scala, скомпилированный в Javascript.
Взято из Цирцея прочитала меня:
scala> импортировать ввод-вывод.circe., ио.цирцея.универсальный.автоматический., io.цирцея.синтаксический анализатор., ио.цирцея.синтаксис. импортируйте io.circe._ импортируйте io.circe.generic.auto._ импортируйте io.circe.parser._ импортируйте io.circe.syntax._
scala> запечатанный признак Foo, определенный признак Foo
scala> панель класса корпуса (xs:Список [Строка]) расширяет Foo определенный класс Bar
scala> класс case Qux(i:Int, d:Опция [Double]) расширяет Foo определенный класс Qux
scala> валь фу:Foo = Qux(13, Немного(14.0)) foo:Foo = Qux(13,Немного (14,0))
scala> foo.asJson.nSpaces res0:String = {"Qux":{"d": 14.0,"i":13}}
scala> decodeFoo res1:cats.data.Xor[io.circe.Ошибка,Foo] = Правильно(Qux(13,Некоторые (14.0)))