如何在Scala/Lift中构造和解析JSON字符串 [英] How can I construct and parse a JSON string in Scala / Lift
问题描述
我正在尝试使用JSON在浏览器和我的应用之间发送数据.
I am attempting to use JSON to send data between the browser and my app.
我正在尝试使用Lift 1.0创建和解析JSON字符串,但是由于某些原因,我无法解析刚刚构建的JSON:
I am attempting to use Lift 1.0 to create and parse JSON strings, but for some reason I am unable to parse the JSON I just constructed:
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消息,该消息也可以再次解析?
How do I programmatically construct a valid JSON message in Scala/Lift that can also be parsed again?
推荐答案
您正在使用Lift 1.0的JsCmd
,它会生成带有单引号字符串的JSON,并尝试使用scala的解析器进行解析,该解析器仅支持double-带引号的字符串.
You are using Lift 1.0's JsCmd
, which produces JSON with single-quoted strings and attempting to parse it with scala's parser, which only supports double-quoted strings.
重要的是要意识到JSON有多个定义.
It is important to realize that there are multiple definitions for JSON.
单引号字符串在JSON中有效吗?
Are single-quoted strings valid in JSON?
- 它们符合 ECMAScript第5版
- 它们与Crockford最初的 RFC 4627 不一致.
- They are according to ECMAScript 5th Ed
- They are not according to Crockford's original RFC 4627
Lift和Scala提供了许多解析JSON的方法,有时版本之间的行为不同.
Lift and Scala provide many ways to parse JSON, sometimes with differing behavior between versions.
这些解析器接受的字符串不相同.
The strings accepted by these parsers are not equivalent.
这里有一些注释和示例,介绍了各种用于生成和解析JSON字符串的方法.
Here are some comments and examples of the various methods to product and parse JSON strings.
- 推荐
- 尽管其名称,这是一个独立的项目,与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 库
- 推荐
- 提供与scala案例类之间的隐式映射
- 当前不支持在控制台中定义的案例类(将抛出
com.thoughtworks.paranamer.ParameterNamesNotFoundException: Unable to get class bytes
) - 下面的示例使用
PublicID
,这是一个预先存在的scala案例类,因此它将在scala控制台上运行. - Recommended
- Provides implicit mapping to/from scala case-classes
- Case-classes defined in the console are not currently supported (will throw a
com.thoughtworks.paranamer.ParameterNamesNotFoundException: Unable to get class bytes
) - The example below uses
PublicID
, a pre-existing scala case-class so that it will work on the scala console.
Parsing JSON with the lift-json library
示例:
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
- 问题中使用的这种解析方法
- Not Recommended - "No longer really supported"
- Scala 2.7.7's parser will not parse single-quoted JSON
- This parsing method used in the question
Parsing JSON in scala 2.7.7 and 2.8.1
示例:
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的util.JSONParser将解析单引号或双引号的JSON字符串:
- Neutral Recommendation
- Lift's util.JSONParser will parse single- or double-quoted JSON strings:
Parsing JSON in Lift 2.0 and 2.2 with util.JSONParser
示例:
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的json.JsonParser不会解析单引号JSON字符串:
- Neutral Recommendation
- Lift's json.JsonParser will not parse single-quoted JSON strings:
Parsing JSON in Lift 2.0 and 2.2 with json.JsonParser
示例:
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解析器均无效
- 注意字符串周围的单引号:
- Not Recommended - output not valid for all JSON parsers
- Note the single-quotations around strings:
Producing JSON with Lift 1.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
res2: String =
{'foo': 4, 'bar': [1, 2, 3]
}
使用Lift 2.0 JsCmd生产JSON
- 中性推荐
- 请注意字符串周围的双引号:
- Neutral Recommendation
- Note the double quotations around strings:
Producing JSON with Lift 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]
}
在scala中生成JSON(已通过2.10测试)
- "不再受真正支持",但是它可以正常工作.
- "No longer really supported", but it works and it's there.
Producing JSON in scala (tested with 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]}
这篇关于如何在Scala/Lift中构造和解析JSON字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!