webentwicklung-frage-antwort-db.com.de

Wie konvertiere ich Scala Map in JSON String?

Zum Beispiel habe ich diesen Kartenwert in Scala:

val m = Map(
    "name" -> "john doe", 
    "age" -> 18, 
    "hasChild" -> true, 
    "childs" -> List(
        Map("name" -> "dorothy", "age" -> 5, "hasChild" -> false),
        Map("name" -> "bill", "age" -> 8, "hasChild" -> false)
    )
)

Ich möchte es in seine JSON-Zeichenfolgendarstellung konvertieren:

{
    "name": "john doe",
    "age": 18,
    "hasChild": true,
    "childs": [
        {
            "name": "dorothy",
            "age": 5,
            "hasChild": false
        },
        {
            "name": "bill",
            "age": 8,
            "hasChild": false
        }
    ]
}

Ich arbeite derzeit an Play Framework v2.3, aber die Lösung muss nicht die Play JSON-Bibliothek verwenden, obwohl es schön wäre, wenn jemand sowohl eine Play- als auch eine Nicht-Play-Lösung anbieten kann.

Das habe ich bisher ohne Erfolg getan:

// using jackson library
val mapper = new ObjectMapper()
val res = mapper.writeValueAsString(m)
println(res)

Ergebnis:

{"empty":false,"traversableAgain":true}

Ich verstehe nicht, warum ich dieses Ergebnis habe.

13
null

Als Nicht-Play-Lösung können Sie die Verwendung von json4s in Betracht ziehen, die einen Wrapper für Jackson bietet und einfach zu bedienen ist. Wenn Sie json4s verwenden, können Sie map in json konvertieren, indem Sie Folgendes verwenden:

write(m)                                        
//> res0: String = {"name":"john doe","age":18,"hasChild":true,"childs":[{"name":"dorothy","age":5,"hasChild":false},{"name":"bill","age":8,"hasChild":false}]}

- Aktualisierung des vollständigen Beispiels--

import org.json4s._
import org.json4s.native.Serialization._
import org.json4s.native.Serialization
implicit val formats = Serialization.formats(NoTypeHints)

 val m = Map(
  "name" -> "john doe",
  "age" -> 18,
  "hasChild" -> true,
  "childs" -> List(
    Map("name" -> "dorothy", "age" -> 5, "hasChild" -> false),
    Map("name" -> "bill", "age" -> 8, "hasChild" -> false)))

 write(m)

Ausgabe:

 res0: String = {"name":"john doe","age":18,"hasChild":true,"childs":[{"name" 
 :"dorothy","age":5,"hasChild":false},{"name":"bill","age":8,"hasChild":false }]}

Alternativer Weg:

import org.json4s.native.Json
import org.json4s.DefaultFormats

Json(DefaultFormats).write(m)
20
mohit

Sie müssen Jackson sagen, wie mit Scala-Objekten umzugehen ist: mapper.registerModule(DefaultScalaModule)

7
Dima
val mapper = new ObjectMapper()
mapper.writeValueAsString(Map("a" -> 1))

ergebnis> {"empty": false, "traversableAgain": true}

===============================

import com.fasterxml.jackson.module.scala.DefaultScalaModule

val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
mapper.writeValueAsString(Map("a" -> 1))

ergebnis> {"a": 1}

4
forcontents
val mymap = array.map {
  case 1 => ("A", 1)
  case 2 => ("B", 2)
  case 3 => ("C", 3)
}
  .toMap

Mit scala.util.parsing.json.JSONObject, brauchst du nur 1 Zeile

import scala.util.parsing.json.JSONObject

JSONObject(mymap).toString()

Wenn Sie mit einem gut definierten Datenmodell arbeiten, können Sie nicht Fallklassen definieren und Play JSON-Makros für die Konvertierung verwenden. d.h.

case class Person(name: String, age: Int, hasChild: Boolean, childs: List[Person])

implicit val fmt = Json.format[Person]

val person = Person(...)

val jsonStr = Json.toJson(person)
1
josephpconley

Mit der Jackson-Bibliothek können Sie ein Java-HashMap-Objekt anstelle eines Scala-Objekts verwenden. Dann können Sie grundsätzlich denselben "erfolglosen" Code verwenden, den Sie bereits geschrieben haben.

import org.codehaus.jackson.map.ObjectMapper
val mapper = new ObjectMapper()
val jmap = new Java.util.HashMap[String, Int]()
jmap.put("dog", 4)
jmap.put("cat", 1)
// convert to json formatted string
val jstring  = mapper.writeValueAsString(jmap)
println(jstring)

kehrt zurück

jstring: String = {"dog":4,"cat":1}    
1
bill_e

Für den Fall, dass jemand nach einer Lösung mit Standardbibliotheken sucht.

def toJson(query: Any): String = query match {
  case m: Map[String, Any] => s"{${m.map(toJson(_)).mkString(",")}}"
  case t: (String, Any) => s""""${t._1}":${toJson(t._2)}"""
  case ss: Seq[Any] => s"""[${ss.map(toJson(_)).mkString(",")}]"""
  case s: String => s""""$s""""
  case null => "null"
  case _ => query.toString
}
0
Paolo