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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (115)

我正在使用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感兴趣,对Ints,字符串,地图和列表感兴趣。我不需要序列化对象,也不需要使反序列化的对象适合当前的类。

任何人都可以指点我与上述库之一的工作方式,或者帮助我建立一个Java库,它可以做我想做的事情吗?

提问于
用户回答回答于

提升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

用案例类提取值

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)))
用户回答回答于

以下是将原始字符串JSON解析为不同Scala JSON库的案例类模型的快速示例:

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)
}

sprayJSON

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)
}

sphereJSON

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"
)

本文受以下文章的启发:在Scala中快速浏览JSON库

扫码关注云+社区