我正在尝试使用 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 消息?

有帮助吗?

解决方案

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

重要的是要认识到 JSON 有多种定义。

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

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

这些解析器接受的字符串并不等效。

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


使用以下命令生成 JSON 电梯 json 图书馆DSL

  • 受到推崇的
  • 尽管它的名字如此,这是一个独立的项目,不依赖于 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]}

解析 JSON 时使用 电梯 json 图书馆

  • 受到推崇的
  • 提供与 scala 案例类之间的隐式映射
  • 当前不支持在控制台中定义的案例类(将抛出 com.thoughtworks.paranamer.ParameterNamesNotFoundException: Unable to get class bytes)
  • 下面的例子使用 公共ID, ,一个预先存在的 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"

在 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

在 Lift 2.0 和 2.2 中解析 JSON util.JSONParser

  • 中性推荐
  • 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))

在 Lift 2.0 和 2.2 中解析 JSON json.JsonParser

  • 中性推荐
  • 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 中生成 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]}

其他提示

看一看瑟茜。这是非常好的使用,它利用一些从无形和的。另外,你可以从斯卡拉编译为JavaScript 使用它。

瑟茜自述摘自:

  

阶>进口io.circe。,io.circe.generic.auto。,io.circe.parser。,   io.circe.syntax。进口io.circe._进口io.circe.generic.auto._   进口io.circe.parser._进口io.circe.syntax ._

     

阶>密封性状富定义性状富

     

阶>情况下类酒吧(XS:列表[字符串])延伸的Foo定义的类酒吧

     

阶>情况下类Qux(ⅰ:中等,d:选项[双])延伸的Foo定义   类Qux

     

阶> VAL FOO:美孚= Qux(13,一些(14.0))富:富=   Qux(13,一些(14.0))

     

阶> foo.asJson.noSpaces RES0:字符串= { “Qux”:{ “d”:14.0, “I”:13}}

     

阶> decodeFoo RES1:   cats.data.Xor [io.circe.Error,富] =右(Qux(13,一些(14.0)))

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top