我如何构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)))