2015-10-24 9 views
10

Questa domanda o simili sono stati pubblicati prima, tuttavia nessuna delle soluzioni funziona più con le ultime librerie. Dopo lunghe ricerche, non ho trovato prove che le ultime versioni delle librerie più famose spray-json o play-json (oi loro plugin) possano gestire questo caso. C'è qualcosa che può analizzare un json di oltre 22 elementi in scala case class? Poiché le classi di casi di scala 2.11 non sono più limitate a 22 elementi. Per favore, solo soluzioni pienamente funzionanti. Esempio json evidente di seguito.scala - parson json di oltre 22 elementi nella classe

{ 
    "a": 1, 
    "b": 2, 
    "c": 3, 
    "d": 4, 
    "e": 5, 
    "f": 6, 
    "g": 7, 
    "h": 8, 
    "i": 9, 
    "j": 10, 
    "k": 11, 
    "l": 12, 
    "m": 13, 
    "n": 14, 
    "o": 15, 
    "p": 16, 
    "q": 17, 
    "r": 18, 
    "s": 19, 
    "t": 20, 
    "u": 21, 
    "v": 22, 
    "w": 23 
} 

UPDATE: Questo è un caso in cui si ha alcun controllo sulla struttura JSON, ad esempio, è recuperato da una terza api partito. Un esempio di JSON tweet di Twitter: http://pastebin.com/h8fHAsd8

+0

E 'pratico per avere tali classi case monolitici? Quali sono i casi d'uso? –

+1

@DominykasMostauskis vedere il mio aggiornamento, per favore. – Caballero

risposta

12

circe fa, con la derivazione automatica di codec supportati da Shapeless. Si noti che, a differenza di decodifica caso di classe di json4s, non c'è nessuna riflessione runtime accadendo qui:

case class Foo(
    a: Int, b: Int, c: Int, d: Int, e: Int, f: Int, g: Int, h: Int, i: Int, 
    j: Int, k: Int, l: Int, m: Int, n: Int, o: Int, p: Int, q: Int, r: Int, 
    s: Int, t: Int, u: Int, v: Int, w: Int 
) 

import io.circe.generic.auto._, io.circe.jawn.decode 

val json = """{ 
    "a": 1, "b": 2, "c": 3, "d": 4, "e": 5, "f": 6, "g": 7, "h": 8, "i": 9, 
    "j": 10, "k": 11, "l": 12, "m": 13, "n": 14, "o": 15, "p": 16, "q": 17, 
    "r": 18, "s": 19, "t": 20, "u": 21, "v": 22, "w": 23 
}""" 

val result: cats.data.Xor[io.circe.Error, Foo] = decode[Foo](json) 

Ecco un minimo build.sbt di file:

scalaVersion := "2.11.7" 

addCompilerPlugin(
    "org.scalamacros" % "paradise" % "2.1.0-M5" cross CrossVersion.full 
) 

libraryDependencies ++= Seq(
    "io.circe" %% "circe-core" % "0.1.1", 
    "io.circe" %% "circe-generic" % "0.1.1", 
    "io.circe" %% "circe-jawn" % "0.1.1" 
) 

La prossima 0.2.0 rilascio (attualmente disponibile come un'istantanea) include una molti miglioramenti alla derivazione generica, ma per un semplice esempio come questo il comportamento 0.1.1 è lo stesso.

+0

Grazie, questo è sicuramente interessante. Ho una domanda bonus però - sarebbe in grado di occuparsi di JSON annidato? – Caballero

+0

@Caballero Sì, certo! Ci sono alcuni casi d'angolo in cui la derivazione automatica si interrompe per le case case nidificate in 0.1.1, ma sono per lo più fissate in 0.2.0. –

+0

Sì, il compilatore sembra strozzarsi sull'enorme json che sto cercando di analizzare con un''espansione implicita divergente per tipo io.circe.Decoder [Foo] a partire dal metodo decodeCaseClass in trait GenericInstances'. Qualche idea quando esce la versione 0.2.0? – Caballero

1

tenta di utilizzare il json4s:

scala> import org.json4s._ 
import org.json4s._ 

scala> import org.json4s.native.JsonMethods._ 
import org.json4s.native.JsonMethods._ 

scala> case class Foo(
    |     a: String, 
    |     b: String, 
    |     c: String, 
    |     d: String, 
    |     e: String, 
    |     f: String, 
    |     g: String, 
    |     h: String, 
    |     i: String, 
    |     j: String, 
    |     k: String, 
    |     l: String, 
    |     m: String, 
    |     n: String, 
    |     o: String, 
    |     p: String, 
    |     q: String, 
    |     r: String, 
    |     s: String, 
    |     t: String, 
    |     u: String, 
    |     v: String, 
    |     w: String 
    |    ) 
defined class Foo 

scala> 

scala>  implicit val formats = DefaultFormats 
formats: org.json4s.DefaultFormats.type = [email protected] 

scala>  val f = parse("{\n \"a\": 1,\n \"b\": 2,\n \"c\": 3,\n \"d\": 4,\n \"e\": 5,\n \"f\": 6,\n \"g\": 7,\n \"h\": 8,\n \"i\": 9,\n \"j\": 10,\n \"k\": 11,\n \"l\": 12,\n \"m\": 13,\n \"n\": 14,\n \"o\": 15,\n \"p\": 16,\n \"q\": 17,\n \"r\": 18,\n \"s\": 19,\n \"t\": 20,\n \"u\": 21,\n \"v\": 22,\n \"w\": 23\n}") 
      .extract[Foo] 
f: Foo = Foo(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23) 
1

Per play-JSON, i play-JSON-estensioni offrono un'estensione che supporta> 22 campi e pochi altri casi d'uso, come la serializzazione di strutture sigillate tratto, oggetti Singleton, ecc

import org.cvogt.play.json.Jsonx 
implicit val jsonFormat = Jsonx.formatCaseClass[Foo] // Instead of Json.format 

https://github.com/cvogt/play-json-extensions

vale certamente la pena di visitare anche circe/argonaut. Non sono sicuro di come si confrontino in termini di caratteristiche e stabilità rispetto alle estensioni play-json/play-json.

+0

Grazie. Ho provato questo, ma non c'è un chiaro esempio di come analizzare un json con> 22 elementi in una classe di case e la conversione implicita di play-json non funziona a causa dello stesso problema di limite di 22 elementi. – Caballero

+0

Basta usare Jsonx.formatCaseClass per la tua case class 22+ in cui normalmente avresti usato Json.format. Tutto il resto dovrebbe rimanere lo stesso. Ancora non funziona? – cvogt

+0

Questo è un esempio sto provando questo: http://pastebin.com/HLJK4wWC Potrei fare qualcosa di sbagliato, ma proprio non riesco a trovare un chiaro esempio di lavoro vicino a questo caso. – Caballero

1

Ispirato da @cvogt e altri miei requisiti personali Ho sviluppato una libreria per gestire in modo trasparente tramite macro i campi> 22 e altre funzionalità.

La biblioteca è here e documentation

L'annotazione JsonFormat crea tramite macro un formato JSON "pimped" che gestiscono un sacco di roba.

Caratteristiche principali sono:

  • gioco JSON per ScalaJS
  • JsonFormat macro annotazione per i più pigri
  • valori dei campi predefiniti popolarono in JSON mancante
  • campo riscrittura for Gioca JSON ("chiave")
  • +22 formatter case field field e altro Play Json Extension
  • Joda Datetime per Scala e ScalaJS
  • forti tipizzati Enum (String e INT) per Scala e ScalaJS
  • Tipi Variant
Problemi correlati