当前位置:  开发笔记 > 编程语言 > 正文

如何在Scala/Lift中构造和解析JSON字符串

如何解决《如何在Scala/Lift中构造和解析JSON字符串》经验,为你挑选了1个好方法。

我试图使用JSON在浏览器和我的应用程序之间发送数据.

我试图使用Lift 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

如何在Scala/Lift中以编程方式构造有效的JSON消息,还可以再次解析?



1> David Carlso..:

您正在使用Lift 1.0 JsCmd,它使用单引号字符串生成JSON,并尝试使用scala的解析器解析它,该解析器仅支持双引号字符串.

重要的是要意识到JSON有多个定义.

单引号字符串在JSON中是否有效?

它们符合ECMAScript第5版

它们不符合Crockford最初的RFC 4627

Lift和Scala提供了许多解析JSON的方法,有时在版本之间有不同的行为.

这些解析器接受的字符串不相同.

以下是产生和解析JSON字符串的各种方法的一些注释和示例.


使用lift-json库DSL 生成JSON

推荐的

尽管它的名字,这是一个单独的项目,不依赖于其余的Lift

例:

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库解析JSON

推荐的

提供与scala案例类的隐式映射

目前不支持在控制台中定义的案例类(将抛出一个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中解析JSON

不推荐 - " 不再真正支持 "

Scala 2.7.7的解析器不会解析单引号的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

使用util.JSONParser解析Lift 2.0和2.2中的JSON

中立建议

Lift的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.JsonParser解析Lift 2.0和2.2中的JSON

中立建议

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

使用Lift 1.0 JsCmd生成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> 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

中立建议

请注意字符串周围的双引号:

例:

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中的Producint JSON(使用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]}


sjson怎么样?
这是一个很好的回应,但现在感觉有点过时了.但是,我不知道是否接受StackOverflow练习对条目进行主要编辑.对我来说主要的问题是应该引用Twitter JSON库(基于scala-json)和Jerkson(使用Jackson)库.此外,对内置Scala支持的引用未提及Scala 2.9.x.
那么,SO的最初目标是避免在线论坛的问题 - 这些帖子永远存在,但最终变得陈旧,没有人会弃用它们或将它们标记为不再相关.鉴于此,加上这是社区维基的答案,我建议你换掉!
说明ECMA第5版是错误的.指定JSON字符串可以有单引号.在页202,规范明确指出双引号.因此,也会使您对多个标准的陈述无效.Crockford定义了一个JSON标准,随后被纳入ECMA第5版.规格.使用单引号生成或验证JSON字符串的实现无效.
推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有