Wie kann ich eine JSON-String in Scala / Aufzug konstruieren und analysieren
Frage
Ich versuche, JSON zu verwenden, um Daten zwischen dem Browser und meiner App zu senden.
Ich versuche, Aufzug 1.0 zu verwenden, um JSON-Strings zu erstellen und zu analysieren, aber aus irgendeinem Grund kann ich nicht die JSON parsen ich gerade aufgebaut:
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
Wie programmatisch ich eine gültige JSON Nachricht in Scala / Aufzug konstruieren, die auch wieder analysiert werden können?
Lösung
Sie verwenden Aufzug 1.0 des JsCmd
, die mit einfachen Anführungszeichen JSON erzeugt und versucht, es mit Scalas Parser zu analysieren, die nur Strings in doppelten Anführungszeichen unterstützt.
Es ist wichtig zu erkennen, dass es mehrere Definitionen für JSON.
Sind Single-Strings in Anführungszeichen gültig in JSON?
- Sie werden nach ECMAScript 5th Ed
- Sie werden nicht nach Crockford Original RFC 4627 rel="nofollow
Lift und Scala viele Möglichkeiten bieten, um JSON zu analysieren, manchmal mit unterschiedlichen Verhalten zwischen den Versionen.
Die Saiten durch diese Parser akzeptiert nicht gleichwertig sind.
Hier sind einige Kommentare und Beispiele für die verschiedenen Methoden zur Produkt und JSON-Strings analysieren.
mit dem Lift-json Bibliothek DSL
- Empfohlene
- Trotz seines Namens, ist dies ein separates Projekt ohne Abhängigkeiten von den übrigen Aufzug
Beispiel:
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]}
Parsing JSON mit der Lift-json Bibliothek
- Empfohlene
- Stellt implizite Zuordnung zu / von scala Fall Klassen
- Case-Klassen in der Konsole definiert werden derzeit nicht unterstützt (ein
com.thoughtworks.paranamer.ParameterNamesNotFoundException: Unable to get class bytes
werfen) - Das folgende Beispiel verwendet
PublicID
, ein bereits bestehende scala Fall-Klasse, so dass es auf der scala Konsole funktionieren.
Beispiel:
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"
Parsing JSON in scala 2.7.7 und 2.8.1
- Nicht empfohlen - „ nicht mehr wirklich unterstützt "
- Scala 2.7.7 Parser nicht in einfachen Anführungszeichen JSON analysieren
- Methode Diese Analyse in der Frage verwendet,
Beispiel:
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
Parsing JSON Service Aufzüge 2.0 und 2.2 mit util.JSONParser
- Neutral-Empfehlung
- Lift des util.JSONParser wird ein- oder doppelten Anführungszeichen JSON-Strings analysieren:
Beispiel:
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))
Parsing JSON Service Aufzüge 2.0 und 2.2 mit json.JsonParser
- Neutral-Empfehlung
- Lifts des json.JsonParser nicht einfache Anführungszeichen JSON-Strings analysieren:
Beispiel:
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...
Producing JSON mit Aufzug 1.0 JsCmd
- Nicht empfohlen - Ausgabe nicht gültig für alle JSON-Parser
- Beachten Sie die Einzelnotierungen um Strings:
Beispiel:
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]
}
Producing JSON mit Aufzug 2.0 JsCmd
- Neutral-Empfehlung
- Beachten Sie die doppelten Anführungszeichen um Strings:
Beispiel:
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]
}
Producing JSON in scala (getestet mit 2.10)
- " nicht mehr wirklich unterstützt “, aber es funktioniert und es ist da.
Beispiel:
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]}
Andere Tipps
Hier finden Sie aktuelle Circe . Es ist wirklich schön zu bedienen und es nutzt einige der neuen Tools von und "https: //github.com/typelevel/cats“rel = "nofollow"> Katzen . Darüber hinaus können Sie es verwenden, um von Scala kompiliert Javascript .
Genommen von der Circe readme :
scala> Import io.circe. , io.circe.generic.auto. , io.circe.parser. , io.circe.syntax. Import io.circe._ Import io.circe.generic.auto._ Import io.circe.parser._ Import io.circe.syntax ._
scala> versiegelt Merkmal Foo definiert Merkmal Foo
scala> case Klasse Bar (xs: Liste [String]) erweitert Foo definiert Klasse Bar
scala> case Klasse qux (i: Int, d: Option [Double]) erstreckt Foo definiert Klasse qux
scala> val foo: Foo = qux (13, Teil (14.0)) foo: Foo = Qux (13, Teil (14.0))
scala> foo.asJson.noSpaces res0: String = { "qux": { "d": 14.0, "i": 13}}
scala> decodeFoo res1: cats.data.Xor [io.circe.Error, Foo] = Right (qux (13, Teil (14.0)))