我如何构build和parsingScala / Lift中的JSONstring
我正在尝试使用JSON在浏览器和我的应用程序之间发送数据。
我正在尝试使用Lift 1.0创build和parsingJSONstring,但出于某种原因,我无法parsing刚刚构build的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
我如何以编程方式在Scala / Lift中构build一个有效的JSON消息,并且可以再次parsing?
您正在使用Lift 1.0的JsCmd
,它使用单引号string生成JSON,并尝试使用只支持双引号string的scalaparsing器进行parsing。
认识到JSON有多个定义是很重要的。
单引号string在JSON中有效吗?
- 他们是根据ECMAScript第五版
- 他们不是根据Crockford原来的RFC 4627
Lift和Scala提供了很多方法来parsingJSON,有时候版本之间会有不同的行为。
这些parsing器接受的string是不相同的。
这里有一些评论和产品和parsingJSONstring的各种方法的例子。
使用lift-json库DSL生成JSON
- 推荐的
- 尽pipe它的名字,这是一个单独的项目,不依赖于电梯的其余部分
例:
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]}
使用lift-json库parsingJSON
- 推荐的
- 提供到scala case-classes的隐式映射
- 在控制台中定义的
com.thoughtworks.paranamer.ParameterNamesNotFoundException: Unable to get class bytes
-classes目前不被支持(会抛出一个com.thoughtworks.paranamer.ParameterNamesNotFoundException: Unable to get class bytes
) - 下面的例子使用
PublicID
,一个预先存在的Scala case-class,以便它可以在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"
在scala 2.7.7和2.8.1中parsingJSON
- 不推荐 – “ 不再真正支持 ”
- Scala 2.7.7的parsing器不会parsing单引号的JSON
- 这个问题中使用的parsing方法
例:
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
使用util.JSONParserparsingLift 2.0和2.2中的JSON
- 中立的build议
- Lift的util.JSONParser将parsing单引号或双引号的JSONstring:
例:
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.JsonParserparsingLift 2.0和2.2中的JSON
- 中立的build议
- Lift的json.JsonParser不会parsing单引号的JSONstring:
例:
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...
使用Lift 1.0 JsCmd生成JSON
- 不推荐 – 输出对所有JSONparsing器无效
- 注意string的单引号:
例:
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] }
使用Lift 2.0 JsCmd生成JSON
- 中立的build议
- 注意string的双引号:
例:
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] }
在scala中生成JSON(用2.10testing)
- “ 不再有真正的支持 ”,但它的工作,它在那里。
例:
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 。 它非常好用,它利用了Shapeless和Cats的一些新工具。 另外,你可以使用它从Scala编译成Javascript 。
采取从Circe自述 :
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>密封特质Foo定义特质Foo
Scala> case class Bar(xs:List [String])扩展了Foo定义的Bar类
scala> case class Qux(i:Int,d:Option [Double])扩展了Foo定义的类Qux
scoo> 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:cats.data.Xor [io.circe.Error,Foo] = Right(Qux(13,Some(14.0)))