问题
I'm working on a simple web application with Scala. The plan is to obtain JSON data from an external API, and insert it into a template (unfortunately, obtaining the data in XML is not an option).
I've tried working with Twitter's scala-json library, but I can't get it to compile properly (the code on github fails to update in sbt, saying standard-project 7.10 is not available and I haven't worked that out yet).
lift-json looks impressive, but appears to be a lot more elaborate than I need right now.
Trying to import a library I've worked with in Java, jsonic, results in various arcane errors. This is too bad because I rather like how straightforward jsonic is.
I've made a bit of progress with the built in scala.util.parsing.json.JSON, but actually I can't tell how to access the elements. I'm somewhat new to Scala, as you may have noted. How do you access the properties of JSONObjects?
scala.util.parsing.json.JSON has a lot of information, but is there a straightforward tutorial on how to use this anywhere?
I'm really only interested in deserializing JSON at the moment, to Ints, Strings, Maps and Lists. I don't have a need to serialize objects or make the deserialized objects fit into a class at the moment.
Can anyone point me to ways to work with one of the aforementioned libraries, or help me get set up with a Java lib that will do what I want?
回答1:
Lift JSON provides several different styles of deserializing JSON. Each have their pros and cons.
val json = JsonParser.parse(""" { "foo": { "bar": 10 }} """)
LINQ style query comprehension:
scala> for { JField("bar", JInt(x)) <- json } yield x
res0: List[BigInt] = List(10)
More examples: http://github.com/lift/lift/blob/master/framework/lift-base/lift-json/src/test/scala/net/liftweb/json/QueryExamples.scala
Extract values with case classes
implicit val formats = net.liftweb.json.DefaultFormats
case class Foo(foo: Bar)
case class Bar(bar: Int)
json.extract[Foo]
More examples: https://github.com/lift/lift/blob/master/framework/lift-base/lift-json/src/test/scala/net/liftweb/json/ExtractionExamples.scala
XPath style
scala> val JInt(x) = json \ "foo" \ "bar"
x: BigInt = 10
Non-type safe values
scala> json.values
res0: Map((foo,Map(bar -> 10)))
回答2:
Here are quick examples of deserialising raw string JSON into case class model for different Scala JSON libraries:
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)
}
Here are dependencies for above examples:
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"
)
This post was inspired by the following article: A quick tour of JSON libraries in Scala
Related SO question: What JSON library to use in Scala?
来源:https://stackoverflow.com/questions/4169153/what-is-the-most-straightforward-way-to-parse-json-in-scala