2010-11-12 15 views
17

Sto lavorando a una semplice applicazione Web con Scala. Il piano è ottenere dati JSON da un'API esterna e inserirli in un modello (sfortunatamente, ottenere i dati in XML non è un'opzione).Qual è il modo più semplice per analizzare JSON in Scala?

Ho provato a lavorare con la libreria scala-json di Twitter, ma non riesco a farlo compilare correttamente (il codice su github non riesce ad aggiornare in sbt, dicendo che il progetto standard 7.10 non è disponibile e non ho ha funzionato ancora).

lift-json sembra impressionante, ma sembra essere molto più elaborato di quello che mi serve in questo momento.

Provare a importare una libreria con Java, jsonic, genera vari errori arcani. Questo è un peccato perché preferisco quanto sia semplice jsonic.

Ho fatto un po 'di progressi con il costruito in scala.util.parsing.json.JSON, ma in realtà non posso dire come accedere agli elementi. Sono un po 'nuovo di Scala, come forse hai notato. Come si accede alle proprietà di JSONObjects?

scala.util.parsing.json.JSON ha un sacco di informazioni, ma c'è un tutorial semplice su come utilizzare questo ovunque?

In questo momento sono interessato solo alla deserializzazione di JSON, a Ints, Strings, Maps ed Elenchi. Al momento non ho bisogno di serializzare oggetti o di far rientrare gli oggetti deserializzati in una classe.

Qualcuno può indicarmi modi per lavorare con una delle librerie citate sopra, o aiutarmi ad essere impostato con una libreria Java che farà ciò che voglio?

risposta

31

Lift JSON offre diversi stili di deserializzazione JSON. Ognuno ha i suoi pro e contro.

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

LINQ query di stile di comprensione:

scala> for { JField("bar", JInt(x)) <- json } yield x 

res0: List[BigInt] = List(10) 

Più esempi: http://github.com/lift/lift/blob/master/framework/lift-base/lift-json/src/test/scala/net/liftweb/json/QueryExamples.scala

valori Estrarre con classi case

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

Altri esempi: https://github.com/lift/lift/blob/master/framework/lift-base/lift-json/src/test/scala/net/liftweb/json/ExtractionExamples.scala

XPath stile

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

x: BigInt = 10 

non digitare i valori sicuri

scala> json.values 

res0: Map((foo,Map(bar -> 10))) 
+0

potrebbe anche ottenere questo uno compilato, mi sa! Grazie per i suggerimenti. – JAL

0

Ecco rapidi esempi di deserialising stringa grezza JSON in modello di classe caso diverso Scala Librerie 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) 
} 

Ecco le dipendenze per gli esempi di cui sopra:

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

Questo post è stato ispirato dal seguente articolo: A quick tour of JSON libraries in Scala

Related SO domanda: What JSON library to use in Scala?

+0

@ defghi1977 Vedere la risposta modificata per i commenti di revisione indirizzati. –

Problemi correlati