如何在Scala/Lift中构造和解析JSON字符串 [英] How can I construct and parse a JSON string in Scala / Lift

查看:117
本文介绍了如何在Scala/Lift中构造和解析JSON字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  • 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控制台上运行.

  • Parsing JSON with the lift-json library

    • 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.
    • 示例:

      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
      • 问题中使用的这种解析方法

      • Parsing JSON in scala 2.7.7 and 2.8.1

        • 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
        • 示例:

          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字符串:

          • Parsing JSON in Lift 2.0 and 2.2 with util.JSONParser

            • Neutral Recommendation
            • Lift's util.JSONParser will parse single- or double-quoted JSON strings:
            • 示例:

              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字符串:

              • Parsing JSON in Lift 2.0 and 2.2 with json.JsonParser

                • Neutral Recommendation
                • Lift's json.JsonParser will not parse single-quoted JSON strings:
                • 示例:

                  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解析器均无效
                  • 注意字符串周围的单引号:

                  • Producing JSON with Lift 1.0 JsCmd

                    • Not Recommended - output not valid for all JSON parsers
                    • Note the single-quotations around strings:
                    • 示例:

                      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

                      • 中性推荐
                      • 请注意字符串周围的双引号:

                      • Producing JSON with Lift 2.0 JsCmd

                        • Neutral Recommendation
                        • Note the double quotations around strings:
                        • 示例:

                          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测试)

                          • "不再受真正支持",但是它可以正常工作.

                          • Producing JSON in scala (tested with 2.10)

                            • "No longer really supported", but it works and it's there.
                            • 示例:

                              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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆