Question

I'm trying to parse JSON in scala and I'm not very successfull. Here's my JSON structure:

{ 
  "data" : "test", 
  "field" : "test", 
  "listObj" : [{ 
      "data" : "testInner1", 
      "field" : "testInner1" 
   } , { 
      "data" : "testInner2", 
      "field" : "testInner2"
   }],
   "obj" : { 
      "data" : "testInner1", 
      "field" : "testInner1" 
   }
}

I'm using lift to parse. Here's my code:

import net.liftweb.json._

implicit val formats = DefaultFormats
case class MyJson(data: String, field: String, obj: MyJson, listObj: List[MyJson])
val json = parse("""
{ 
  "data" : "test", 
  "field" : "test", 
  "listObj" : [{ 
      "data" : "testInner1", 
      "field" : "testInner1" 
   } , { 
      "data" : "testInner2", 
      "field" : "testInner2"
   }],
   "obj" : { 
      "data" : "testInner1", 
      "field" : "testInner1" 
   }
}""")
println(json.extract[Query])

I've god the following exception:

Caused by: net.liftweb.json.MappingException: No usable value for operation
Did not find value which can be converted into java.lang.String
at net.liftweb.json.Meta$.fail(Meta.scala:191)
at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:357)
at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:317)
at net.liftweb.json.Extraction$$anonfun$13.apply(Extraction.scala:253)
at net.liftweb.json.Extraction$$anonfun$13.apply(Extraction.scala:253)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.immutable.List.foreach(List.scala:318)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
at scala.collection.AbstractTraversable.map(Traversable.scala:105)
at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:253)
at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:286)
at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:315)
at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:351)
... 34 more
Caused by: net.liftweb.json.MappingException: Did not find value which can be converted into java.lang.String
at net.liftweb.json.Meta$.fail(Meta.scala:191)
at net.liftweb.json.Extraction$.convert(Extraction.scala:403)
at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:314)
at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:351)
... 46 more

I've tried using json4s but I could manage to make it parse into case classes. When I remove the obj and objList from my JSON, it works well.

Anyone can point me out some way to parse this kind of structure to read it in Scala?

Was it helpful?

Solution

Change your case class definition so that obj is an optional value:

 case class MyJson(data: String, 
    field: String, 
    // obj: MyJson,        // from 
    obj: Option[MyJson],   // to
    listObj:  List[MyJson])

This is needed so that the json extractor can still produce and instance of MyJson even if the json lacks an "obj" field (which it does within the nested structures in your example).

This isn't needed for listObj because an absence of a "listObj" field in the json can still be represented as an empty list of List[MyJson].

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top