2015-01-08 4 views
10

Attualmente sto estraendo alcune metriche da diverse origini dati e memorizzandole in una mappa di tipo Map[String,Any] dove la chiave corrisponde al nome della metrica e il valore corrisponde al valore di metrica . Ho bisogno che questo sia più o meno generico, il che significa che i tipi di valori possono essere tipi primitivi o elenchi di tipi primitivi.Mappa [String, Any] per compattare json string utilizzando json4s

Vorrei serializzare questa mappa su una stringa in formato JSON e per quello sto usando la libreria json4s. Il fatto è che non sembra possibile e non vedo una possibile soluzione per questo. Mi sarei aspettato qualcosa di simile a quanto segue per lavorare fuori dalla scatola :)

val myMap: Map[String,Any] = ... // extract metrics 
val json = myMap.reduceLeft(_ ~ _) // create JSON of metrics 

Navigazione attraverso source code Ho visto json4s fornisce le conversioni implicite al fine di trasformare tipi primitivi per JValue 's ed anche per convertire Traversable[A]/Map[String,A]/Option[A]-JValue E '(con la restrizione di essere disponibile una conversione implicita da A a JValue, che capisco in realtà significa che A è un tipo primitivo). L'operatore ~ offre un buon modo di costruire JObject su JField, che è solo un alias di tipo per (String, JValue).

In questo caso, i valori tipo di mappa è Any, quindi le conversioni implicite non avvengono e quindi il compilatore tiri il seguente errore:

    value ~ is not a member of (String, Any) 
[error]    val json = r.reduceLeft(_ ~ _) 

C'è una soluzione per quello che voglio realizzare?

+0

Se ho capito bene e si desidera solo per serializzare 'myMap', perché non chiamare' Serialization.write (myMap) 'direttamente? – edi

+1

@ user3567830 Voglio una rappresentazione stringa JSON di 'myMap', che è lo scopo di usare una libreria di scala JSON come' json4s' – jarandaf

+1

Sì, 'org.json4s.jackson.Serialization.write (myMap)' fa esattamente questo. (Ho usato la versione jackson di json4s, ma questo dovrebbe funzionare anche per la versione nativa). – edi

risposta

26

Poiché si sta effettivamente cercando solo la rappresentazione della stringa JSON di myMap, è possibile utilizzare direttamente l'oggetto Serialization. Ecco un piccolo esempio (se si utilizza la versione nativa di json4s cambiare l'importazione org.json4s.native.Serialization):

EDIT: aggiunto formats implicita

import org.json4s.jackson.Serialization 

implicit val formats = org.json4s.DefaultFormats 

val m: Map[String, Any] = Map(
    "name "-> "joe", 
    "children" -> List(
    Map("name" -> "Mary", "age" -> 5), 
    Map("name" -> "Mazy", "age" -> 3) 
    ) 
) 
// prints {"name ":"joe","children":[{"name":"Mary","age":5},{"name":"Mazy","age":3}]} 
println(Serialization.write(m)) 
+3

Solo per ulteriori riferimenti, è richiesta un'istanza implicita 'Formats', altrimenti viene visualizzato il seguente errore:' Nessun org.json4s.Formats trovato. Prova a portare un'istanza di org.json4s.Formats nell'ambito o utilizzare org.json4s.DefaultFormats. Ad esempio, 'implicit val formats = org.json4s.DefaultFormats' risolve il problema. – jarandaf

+0

Grazie, ho aggiornato la risposta. – edi

0

json4s ha metodo per esso.

pretty(render(yourMap))