Question

Je tente d'utiliser JSON pour envoyer des données entre le navigateur et mon application.

Je cherche à utiliser Lift 1.0 pour créer et analyser des chaînes JSON, mais pour une raison que je ne peux pas analyser le JSON Je viens construisais:

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

Comment puis-je construis un message JSON programme valable dans Scala / Lift qui peut également être analysé à nouveau?

Était-ce utile?

La solution

Vous utilisez le JsCmd de Lift 1.0, qui produit JSON avec des chaînes entre guillemets simples et en essayant de l'analyser avec l'analyseur de scala, qui ne supporte que les chaînes entre guillemets doubles.

Il est important de se rendre compte qu'il existe plusieurs définitions pour JSON.

sont des chaînes entre guillemets simples valable dans JSON?

Lift et Scala offrent de nombreuses façons de parser JSON, parfois avec des comportements différents entre les versions.

Les chaînes acceptées par ces parseurs ne sont pas équivalents.

Voici quelques commentaires et des exemples des différentes méthodes de produits et analyser des chaînes JSON.


La production JSON avec le plate-forme élévatrice JSON DSL bibliothèque

  • recommandé
  • Malgré son nom, c'est un projet distinct sans dépendances sur le reste de levage

exemple:

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 avec le Parsing rel="nofollow plate-forme élévatrice JSON bibliothèque

  • recommandé
  • Fournit la cartographie implicite / des classes de cas-scala
  • Case-classes définies dans la console ne sont pas actuellement pris en charge (jetteront un com.thoughtworks.paranamer.ParameterNamesNotFoundException: Unable to get class bytes)
  • L'exemple ci-dessous utilise PublicID, un cas de classe scala préexistante afin qu'il fonctionne sur la console scala.

exemple:

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 dans scala Parsing 2.7.7 et 2.8.1

  • Non recommandé - « plus vraiment soutenu "
  • l'analyseur de Scala 2.7.7 n'analysera pas JSON guillemets simples
  • Cette méthode d'analyse utilisée dans la question

exemple:

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 Ascenseur 2,0 et 2,2 avec util.JSONParser

  • Recommandation neutre
  • util.JSONParser de Lift analysera les chaînes JSON simple ou double cité:

exemple:

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 Ascenseur 2,0 et 2,2 avec json.JsonParser

  • Recommandation neutre
  • json.JsonParser de levage ne sera pas analyser des chaînes JSON entre guillemets simples:

exemple:

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...

Production JSON avec Lift 1.0 JsCmd

  • Non recommandé - sortie non valable pour tous les parseurs JSON
  • Notez les mono-cotations autour de chaînes:

exemple:

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]
}

Production JSON avec Lift 2.0 JsCmd

  • Recommandation neutre
  • Notez les doubles guillemets autour des chaînes:

exemple:

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]
}

La production JSON dans scala (testé avec 2.10)

exemple:

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]}

Autres conseils

Jetez un oeil à Circé . Il est vraiment agréable à utiliser et il tire parti de quelques-uns des nouveaux outils de et Shapeless Chats . De plus, vous pouvez l'utiliser à partir Scala compilé Javascript .

Tiré du Circé readme :

  

scala> io.circe d'importation. , io.circe.generic.auto. , io.circe.parser. ,   io.circe.syntax. import io.circe._ io.circe.generic.auto._ import   importation io.circe.syntax importation io.circe.parser._ ._

     

scala> trait scellé Foo trait défini Foo

     

scala> Bar cas de classe (xs: Liste [String]) étend barre de classe Foo défini

     

scala> classe affaire qux (i: Int, d: Option [Double]) étend Foo défini   classe qux

     

scala> val foo: Foo = qux (13, Some (14,0)) foo: Foo =   Qux (13, Some (14,0))

     

scala> foo.asJson.noSpaces res0: String = { "qux": { "d": 14,0, "i": 13}}

     

scala> decodeFoo RES1:   cats.data.Xor [io.circe.Error, Foo] = Droite (qux (13, Some (14,0)))

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top