代码之家  ›  专栏  ›  技术社区  ›  JAL

在Scala中解析JSON最直接的方法是什么?

  •  17
  • JAL  · 技术社区  · 15 年前

    我正在用Scala开发一个简单的web应用程序。计划是从外部API获取JSON数据,并将其插入到模板中(不幸的是,用XML获取数据不是一个选项)。

    我试过使用Twitter的scala json库,但无法正确编译(github上的代码无法在sbt中更新,表示标准项目7.10不可用,我还没有解决这个问题)。

    lift json看起来令人印象深刻,但似乎比我现在需要的要复杂得多。

    尝试导入我在Java中使用过的库jsonic会导致各种神秘错误。这太糟糕了,因为我更喜欢jsonic的直截了当。

    我已经在内置scala.util.parsing.json.json方面取得了一些进展,但实际上我不知道如何访问这些元素。你可能已经注意到,我对Scala有点陌生。如何访问JSONObjects的属性?

    scala.util.parsing.json.JSON 有很多信息,但是有没有一个简单的教程介绍如何在任何地方使用它?

    我现在只对反序列化JSON、int、string、map和list感兴趣。我现在不需要序列化对象或使反序列化的对象适合类。

    有谁能告诉我如何使用前面提到的库之一,或者帮助我建立一个可以做我想做的事情的Java库?

    2 回复  |  直到 8 年前
        1
  •  31
  •   Joni    15 年前

    Lift JSON提供了几种不同风格的反序列化JSON。各有利弊。

    val json = JsonParser.parse(""" { "foo": { "bar": 10 }} """)
    

    LINQ风格查询理解:

    scala> for { JField("bar", JInt(x)) <- json } yield x 
    
    res0: List[BigInt] = List(10)
    

    更多示例: http://github.com/lift/lift/blob/master/framework/lift-base/lift-json/src/test/scala/net/liftweb/json/QueryExamples.scala

    使用case类提取值

    implicit val formats = net.liftweb.json.DefaultFormats 
    case class Foo(foo: Bar) 
    case class Bar(bar: Int) 
    json.extract[Foo] 
    

    更多示例: https://github.com/lift/lift/blob/master/framework/lift-base/lift-json/src/test/scala/net/liftweb/json/ExtractionExamples.scala

    XPath样式

    scala> val JInt(x) = json \ "foo" \ "bar"
    
    x: BigInt = 10
    

    非类型安全值

    scala> json.values
    
    res0: Map((foo,Map(bar -> 10)))
    
        2
  •  0
  •   Mario Galic    8 年前

    下面是将原始字符串JSON反序列化为不同Scala JSON库的case类模型的快速示例:

    play-json

    import play.api.libs.json._
    
    case class User(id: Int, name: String)
    
    object User {
      implicit val codec = Json.format[User]
    }
    
    object PlayJson extends App {
      val string = """{"id": 124, "name": "John"}"""
      val json = Json.parse(string)
      val user = json.as[User]
      println(user)
    }
    

    lift-json

    import net.liftweb.json._
    
    case class User(id: Int, name: String)
    
    object LiftJson extends App {
      implicit val codec = DefaultFormats
      val string = """{"id": 124, "name": "John"}"""
      val json = parse(string)
      val user = json.extract[User]
      println(user)
    }
    

    spray-json

    import spray.json._
    import DefaultJsonProtocol._
    
    case class User(id: Int, name: String)
    
    object UserJsonProtocol extends DefaultJsonProtocol {
      implicit val codec = jsonFormat2(User)
    }
    
    object SprayJson extends App {
      import UserJsonProtocol._
      val string = """{"id": 124, "name": "John"}"""
      val json = string.parseJson
      val user = json.convertTo[User]
      println(user)
    }
    

    sphere-json

    import io.sphere.json.generic._
    import io.sphere.json._
    
    case class User(id: Int, name: String)
    
    object SphereJson extends App {
      implicit val codec = deriveJSON[User]
      val string = """{"id": 124, "name": "John"}"""
      val user = fromJSON[User](string)
      println(user)
    }
    

    argonaut

    import argonaut._ 
    import Argonaut._
    
    case class User(id: Int, name: String)
    
    object ArgonautJson extends App {
      implicit def codec = casecodec2(User.apply, User.unapply)("id", "name")
      val string = """{"id": 124, "name": "John"}"""
      val user = string.decodeOption[User]
      println(user)
    }
    

    circe

    import io.circe.generic.auto._
    import io.circe.parser._
    
    case class User(id: Int, name: String)
    
    object CirceJson extends App {
      val string = """{"id": 124, "name": "John"}"""
      val user = decode[User](string)
      println(user)
    }
    

    以下是上述示例的依赖项:

    resolvers += Resolver.bintrayRepo("commercetools", "maven")
    
    libraryDependencies ++= Seq(
    
      "com.typesafe.play" %% "play-json"      % "2.6.7",
      "net.liftweb"       %% "lift-json"      % "3.1.1",
      "io.spray"          %% "spray-json"     % "1.3.3",
      "io.sphere"         %% "sphere-json"    % "0.9.0",
      "io.argonaut"       %% "argonaut"       % "6.2",
      "io.circe"          %% "circe-core"     % "0.8.0",
      "io.circe"          %% "circe-generic"  % "0.8.0",
      "io.circe"          %% "circe-parser"   % "0.8.0"
    )
    

    这篇文章的灵感来自以下文章: A quick tour of JSON libraries in Scala

    相关SO问题: What JSON library to use in Scala?