2010-11-12 37 views
17

我正在使用Scala开发简单的Web应用程序。该计划是从外部API获取JSON数据,并将其插入模板(不幸的是,以XML获取数据不是一种选择)。在Scala中解析JSON最直接的方法是什么?

我已经尝试使用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库,它可以做我想做的事吗?

回答

31

提升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))) 
+0

不妨得到这个编译,我想!感谢您的提示。 – JAL 2010-11-13 20:54:04

0

这里有deserialising原始字符串JSON成案类模型不同的Scala的简单的例子JSON库:

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?

+0

@ defghi1977请参阅已解决的评论意见的编辑答案。 – 2017-11-02 21:45:37

相关问题