简体   繁体   中英

Generic Json Parsing in Scala

I have aa generic JSON where all keys and values are string.

Example1:

[
  {
    "key1": "value1"
  },
  {
    "key1": "value2"
  }
]

but the JSON can also be: Example2:

[
  {
    "key1": "value1",
    "key2": "value2"
  },
  {
    "key1": "value3",
    "key2": "value4"
  }
]

I want to convert the JSON to a Map. Example 1 will convert to Map[String, String]

Example 2 will convert to List[Map[String, String]]

So basically I want to convert the JSON to Map and use it as following:

map("key1")("key2")("key3")

to get the final result value3.

Please help!!

Using play-json you can convert Json to Map using validate . Validate returns JsResult which can be JsSuccess(data,path) or JsError(errors) . Pattern match to get the map out of it.

Check if str is of case 1 if not fallback to case 2

Json.parse(jsonString).validate[Map[String, String]].getOrElse(json.validate[List[Map[String,String]]])

Case 1: For Map[String, String]

import play.api.libs.json._
val result = Json.parse(someValidJsonString).validate[Map[String, String]]
result match {
  case JsSuccess(map, _) => map
  case JsError(errors) => Logger.error("json parsing failed")
}

Case 2: For List[Map[String, String]]

import play.api.libs.json._
    val result = Json.parse(someValidJsonString).validate[List[Map[String, String]]]
    result match {
      case JsSuccess(list, _) => list
      case JsError(errors) => Logger.error("json parsing failed")
    }

Here someValidJsonString is the json string you want to convert to Map

If you are using sbt project then add play-json dependency to your project.

build.sbt

libraryDependencies ++= Seq("com.typesafe.play" %% "play-json" % "2.5.4")

Scala REPL

scala> import play.api.libs.json._
import play.api.libs.json._

scala> val map = Map("java" -> 1, "scala" -> 2)
map: scala.collection.immutable.Map[String,Int] = Map(java -> 1, scala -> 2)

scala> Json.toJson(map).validate[Map[String, Int]]
res3: play.api.libs.json.JsResult[Map[String,Int]] = JsSuccess(Map(java -> 1, scala -> 2),)

scala> val result = Json.toJson(map).validate[Map[String, Int]]
result: play.api.libs.json.JsResult[Map[String,Int]] = JsSuccess(Map(java -> 1, scala -> 2),)

scala> result match { case JsSuccess(data, _) => data case JsError(errors) => Unit}
res4: Object = Map(java -> 1, scala -> 2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM