我正在尝试使用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消息,该消息也可以再次解析?
答案 0 :(得分:87)
您正在使用Lift 1.0的JsCmd
,它使用单引号字符串生成JSON,并尝试使用scala的解析器解析它,该解析器仅支持双引号字符串。
重要的是要意识到JSON有多种定义。
单引号字符串在JSON中是否有效?
Lift和Scala提供了许多解析JSON的方法,有时候版本之间会有不同的行为。
这些解析器接受的字符串不等效。
以下是产生和解析JSON字符串的各种方法的一些注释和示例。
示例:
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]}
com.thoughtworks.paranamer.ParameterNamesNotFoundException: Unable to get class bytes
)PublicID
,一个预先存在的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>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
示例:
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))
示例:
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...
示例:
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]
}
示例:
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> 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]}
答案 1 :(得分:0)
看看Circe。它非常好用,它利用了Shapeless和Cats中的一些新工具。另外,您可以使用Scala compiled to Javascript。
取自Circe readme:
阶> 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 ._
阶>密封特性Foo定义特质Foo
阶> case类Bar(xs:List [String])扩展了Foo定义的类Bar
阶> case类Qux(i:Int,d:Option [Double])扩展了Foo定义 Qux课程
阶> val foo:Foo = Qux(13,Some(14.0))foo:Foo = Qux(13,一些(14.0))
阶> foo.asJson.noSpaces res0:String = {" Qux":{" d":14.0," i":13}}
阶> decodeFoo res1: cats.data.Xor [io.circe.Error,Foo] =右(Qux(13,Some(14.0)))