Reputation: 35
I'm trying to parse json string with scala and playframework, I've read doc but still I'm stuck. I got:
val jsonStr = """{
| "metric": "java.lang.Memory.HeapMemoryUsage.committed",
| "tags": {
| "instanceId": "ubuntu",
| "runId": "B_name_of_the_app-c4m8_0_2016-01-01_23-31-34"
| },
| "aggregateTags": [],
| "dps": {
| "1455711498": 8.71890944E8,
| "1455711558": 9.10688256E8,
| "1455711618": 9.24319744E8,
| "1455711678": 8.47773696E8,
| "1455711738": 9.35329792E8,
| "1455711798": 9.53679872E8,
| "1455714981": 1.983905792E9,
| "1455715041": 2.054684672E9,
| "1455715101": 2.05520896E9
| }
| }""".stripMargin
according to playframework doc I created classes to parse this thing:
// start of the scala file
import play.api.libs.json.{JsPath, Json, Reads}
import play.api.libs.functional.syntax._
case class Metric(metricName: String, tags: Tags, aggregateTags: Option[Seq[String]], dps: Seq[Map[String,Double]])
object Metric{
implicit val metricReads: Reads[Metric] = (
(JsPath \ "metric").read[String] and
(JsPath \ "tags").read[Tags] and
(JsPath \ "aggreagateTags").readNullable[Seq[String]] and
(JsPath \ "dps").read[Seq[Map[String,Double]]] //this one is tricky
)(Metric.apply _)
}
case class Tags(instanceId:String, runId: String)
object Tags{
implicit val tagsReads: Reads[Tags] = (
(JsPath \ "instanceId").read[String] and (JsPath \ "runId").read[String]
)(Tags.apply _)
}
Json.parse(jsonStr).validate[Metric]
// end of the scala file Unfortunately validation results with:
res0: play.api.libs.json.JsResult[Metric] = JsError(List((//dps,List(ValidationError(List(error.expected.jsarray),WrappedArray())))))
I'm not sure how to solve this problem, also tried parse dps' as a separate class but also didn't work..Any tips?
Upvotes: 0
Views: 258
Reputation: 160083
You have (JsPath \ "dps").read[Seq[Map[String,Double]]]
but dps
in your JSON is not a Seq
but a single entry - changing that part of the reader to (JsPath \ "dps").read[Map[String,Double]]
will fix the problem.
Upvotes: 2