Как я могу построить и проанализировать строку 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, которое также может быть проанализировано снова?
2 ответа:
вы используете лифт 1.0 л!--8-->, который создает JSON с строками в одинарных кавычках и пытается проанализировать его с помощью синтаксического анализатора scala, который поддерживает только строки в двойных кавычках.
важно понимать, что существует несколько определений для JSON.
допустимы ли строки в одинарных кавычках в JSON?
- они согласно ECMAScript 5th Ed
- они не соответствуют оригиналу Крокфорда 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-формате библиотека
- рекомендовано
- обеспечивает неявное отображение в / из Scala case-classes
- Case-классы, определенные в консоли, в настоящее время не поддерживаются (бросит
com.thoughtworks.paranamer.ParameterNamesNotFoundException: Unable to get class bytes
)- в приведенном ниже примере используется
PublicID
, уже существующий класс Scala case, чтобы он работал на консоли 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 в лифте 2.0 и 2.2 с util.JSONParser
- Нейтральная Рекомендация
- лифт в утиль.JSONParser будет анализировать строки 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 в лифте 2.0 и 2.2 с в формате JSON.JsonParser
- нейтральный Рекомендация
- лифт json.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.apply(JsonParser.scala:172) at net.liftweb.json.JsonParser$$anonfun.apply(JsonParser.scala:129) at net.liftweb.json.JsonParse...
производить JSON с подъемом 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 с подъемом 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] }
Producint 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.
взято с Circe readme:
scala > импорт ввода-вывода.Цирцея., io.Цирцея.родовой.автоматический., io.Цирцея.синтаксический анализатор., Ио.Цирцея.синтаксис. импорт ввода-вывода.Цирцея._ импорт Ио.Цирцея.родовой.автоматический._ импорт Ио.Цирцея.синтаксический анализатор._ import io.Цирцея.синтаксис._
scala > запечатанный признак Foo определенный признак Foo
scala > case class Bar (xs: List[String]) расширяет Foo определенный класс Bar
scala > case class Qux (i: Int, d: Option[Double]) расширяет Foo defined Qux класс
scala > val foo: Foo = Qux (13, Некоторые(14.0)) foo: Foo = Qux(13,Некоторые(14.0))
scala> foo.asJson.noSpaces res0: String = {"Qux": {"d": 14.0,"i": 13}}
scala> decodeFoo res1: кошки.данные.Гаммирования[Ио.Цирцея.Error, Foo] = Right(Qux(13,Some (14.0)))