web-dev-qa-db-fra.com

Comment convertir Scala Map en JSON String?

Par exemple, j'ai cette valeur de carte dans 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)
    )
)

Je souhaite le convertir en représentation de chaîne JSON:

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

Je travaille actuellement sur Play Framework v2.3, mais la solution n'a pas besoin d'utiliser la bibliothèque Play JSON, bien que ce soit bien si quelqu'un peut fournir à la fois une solution Play et une solution non Play.

C'est ce que j'ai fait jusqu'à présent sans succès:

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

Résultat:

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

Je ne comprends pas pourquoi j'ai eu ce résultat.

13
null

En tant que solution non-play, vous pouvez envisager d’utiliser json4s , qui fournit une enveloppe autour de Jackson et sa facilité d’utilisation. Si vous utilisez json4s, vous pouvez convertir map en json simplement en utilisant:

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

--Mise à jour pour inclure l'exemple complet--

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)

Sortie:

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

Manière alternative:

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

Json(DefaultFormats).write(m)
20
mohit

Vous devez dire à Jackson comment traiter les objets scala: mapper.registerModule(DefaultScalaModule)

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

résultat> {"empty": false, "traversableAgain": true}

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

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

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

résultat> {"a": 1}

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

Avec scala.util.parsing.json.JSONObject, vous n’avez besoin que d’une ligne

import scala.util.parsing.json.JSONObject

JSONObject(mymap).toString()

Si vous travaillez avec un modèle de données bien défini, pourquoi ne pas définir des classes de cas et utiliser des macros Lecture JSON pour gérer la conversion? c'est à dire.

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

Une chose que vous pouvez faire avec la bibliothèque Jackson est d’utiliser un objet Java HashMap, au lieu d’un objet Scala. Vous pouvez ensuite utiliser le même code "sans succès" que vous avez déjà écrit.

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)

résultats

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