Hello I would like to transform json object into map using implicit Reads. With the code below I run into a StackOverflow error, any one could see what the problem is :
"pass": {
"key-1": {
"field1": "aaaa",
"field2": "aaaa"
},
"key-2": {
"field1": "aaaa",
"field2": "aaaa"
},
"key-3": {
"field1": "aaaa",
"field2": "aaaa"
}
}
case class Pass(field1: String, field2: String)
implicit val mapReads: Reads[Map[String, Pass]] = new Reads[Map[String, Pass]] {
def reads(jv: JsValue): JsResult[Map[String, Pass]] =
JsSuccess(jv.as[Map[String, Pass]].map{
case (k, v) => k -> v.asInstanceOf[Pass]
})
}
val passMap = (json \ "pass").validate[Map[String, Pass]]
Here is the stack error :
java.lang.StackOverflowError
at play.api.libs.json.JsReadable$class.as(JsReadable.scala:23)
at play.api.libs.json.JsObject.as(JsValue.scala:124)
at com.MyHelper$$anon$1.reads(MyHelper.scala:51)
at play.api.libs.json.Format$$anon$3.reads(Format.scala:65)
at play.api.libs.json.JsValue$class.validate(JsValue.scala:17)
at play.api.libs.json.JsObject.validate(JsValue.scala:124)
at play.api.libs.json.JsReadable$class.as(JsReadable.scala:23)
at play.api.libs.json.JsObject.as(JsValue.scala:124)
Maybe you will be more likely to create a MapPass class case and use Json.format to do the work for you!
import play.api.libs.json._
val a: String = """{
"pass": {
"key-1": {
"field1": "aaaa",
"field2": "aaaa"
},
"key-2": {
"field1": "aaaa",
"field2": "aaaa"
},
"key-3": {
"field1": "aaaa",
"field2": "aaaa"
}
}
}"""
case class Pass(field1: String, field2: String)
case class MapPass(pass: Map[String, Pass])
implicit val passFormat: Format[Pass] = Json.format[Pass]
implicit val mapPassFormat: Format[MapPass] = Json.format[MapPass]
val json = Json.parse(a)
val mapPassJsResult = json.validate[MapPass]
val mapPass = mapPassJsResult.get
print(mapPass.pass.mkString("\n"))
It worked like that for me: