كيف يمكنني بناء وتحليل سلسلة JSON في Scala / LIFT
سؤال
أحاول استخدام JSON لإرسال البيانات بين المتصفح وتطبيقي.
أنا أحاول استخدام الرفع 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 التي يمكن أيضا تحليلها مرة أخرى؟
المحلول
أنت تستخدم رفع 1.0 JsCmd
, ، والتي تنتج JSON مع سلاسل واحدة مقتبسة ومحاولة تحليلها مع محلل SCALA، والتي تدعم فقط سلاسل مزدوجة.
من المهم أن ندرك أن هناك تعاريف متعددة ل JSON.
هي سلاسل واحدة مقتبسة صالحة في جون؟
- هم وفقا ecmascript 5th ed.
- انهم ليسوا وفقا لكروكفورد الأصلي RFC 4627.
توفر LIFT و SCALA العديد من الطرق لتحليل JSON، وأحيانا مع سلوك مختلف بين الإصدارات.
السلاسل المقبولة من قبل هذه المحللين ليست معادلة.
فيما يلي بعض التعليقات والأمثلة على الطرق المختلفة للمنتج وتحليل سلاسل JSON.
إنتاج جون مع رفع json. مكتبة DSL.
- مستحسن
- على الرغم من اسمها، هذا مشروع منفصل بدون تبعيات على بقية المصعد
مثال:
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
- لا يتم دعم فئات الأحرف المحددة في وحدة التحكم حاليا (سوف رمي
com.thoughtworks.paranamer.ParameterNamesNotFoundException: Unable to get class bytes
) - المثال أدناه يستخدم
واهن
, ، فئة 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's Parser لن تحليل 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.
- توصية محايدة
- سيقوم Util.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.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 مع رفع 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]
}
إنتاج 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]}
نصائح أخرى
إلقاء نظرة على Circe. وبعد من الجميل حقا استخدامها وتزود بعض الأدوات الجديدة من بشع و القطط. وبعد بالإضافة إلى ذلك، يمكنك استخدامه من تجميع Scala إلى جافا سكريبت.
مأخوذة من Circe Readme.:
Scala> استيراد IO.Circe., ، io.circe.generic.auto., ، io.circe.parser.، io.circe.syntax. استيراد IO.Circe._ استيراد IO.Circe.generic.Auto._ استيراد IO.Circe.parser._ استيراد io.circe.syntax._
Scala> سمة مختومة فو العاظر المحدد فو
SCALA> شريط الفئة الحالة (XS: قائمة [سلسلة]) يمتد حانة فئة فو
Scala> Case Class Qux (i: int، D: خيار [مزدوج]) يمتد فو فئة كوكس المحددة
Scala> فال فو: فو = كوكس (13، بعض (14.0)) foo: foo = qux (13، بعض (14.0))
Scala> foo.asjson.nospaces res0: string = {"qux": {"D": 14.0، "i": 13}}
Scala> decodefoo res1: cats.data.xor [io.circe.Error، foo] = يمين (كوكس (13، بعض (14.0)))