0

I have json file with content:

{
  "ruleName": "rule1",
  "steps": [{
    "stepIdentifer": "SI1"
  }, {
    "stepIdentifer": "SI2"
  }]
}

I am trying to map it to scala class (Rule) using following code:

import java.io.FileInputStream
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.databind.{DeserializationFeature, ObjectMapper}
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
import com.google.gson.GsonBuilder

def main(args: Array[String]): Unit = {
    val file:String = "<file_path>";    
    val stream = new FileInputStream(file)
    val mapper = new ObjectMapper with ScalaObjectMapper
    mapper.registerModule(DefaultScalaModule)
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    val rule: Rule = mapper.readValue[Rule](stream)    
    val gson = new GsonBuilder().setPrettyPrinting().create()
    println(gson.toJson(rule)) // PRINT_STATEMENT
  }

Output from print statement is:

{
  "ruleName": "rule1",
  "steps": {}
}

Json file contains "steps", but in output, it is not mapped with member class RuleStep.

Scala Class definition of Rule class is as follow:

class Rule {
  var ruleName: String = null;
  var steps:List[RuleStep] = null;
}

Scala Class definition of RuleStep class is as follow:

class RuleStep {
  var stepIdentifer: String = null
}

I am not able to understand what I missed? What should I do to match member class (RuleStep) with nested Json (attribute key: "steps")?

Versions:

Scala = 2.11
libraryDependencies += "com.google.code.gson" % "gson" % "2.6.2"
libraryDependencies += "com.fasterxml.jackson.core" % "jackson-databind" % "2.6.2"
libraryDependencies += "com.fasterxml.jackson.core" % "jackson-core" % "2.6.2"
user811602
  • 1,314
  • 2
  • 17
  • 47
  • Could you share your `build.sbt` file, namely: scala version, jackson databind and gson dependencies? – Duelist Oct 16 '18 at 10:00
  • @Duelist I have updated the post for versions. – user811602 Oct 16 '18 at 10:07
  • Is the class definition correct? Scala is new to me and I have seen examples of "case" class for json-class mapping. question posted here is in very simplified form. I have four level of depth of member classes – user811602 Oct 16 '18 at 10:44
  • It's better to use case classes because they give you a lot of useful things, you can read [here](https://docs.scala-lang.org/tour/case-classes.html). Now I'm trying to understand why gson converts `rule` with `steps` loss – Duelist Oct 16 '18 at 10:49
  • Probably gson doesn't work with Scala classes properly. There was a [similar problem](https://stackoverflow.com/questions/6785465/how-can-i-use-gson-in-scala-to-serialize-a-list). But `mapper.writeValueAsString(rule)` works well and returns `{"ruleName":"rule1","steps":[{"stepIdentifer":"SI1"},{"stepIdentifer":"SI2"}]}`. – Duelist Oct 16 '18 at 10:55

1 Answers1

1

Probably Gson doesn't work with Scala classes properly. There was a similar problem. But mapper.writeValueAsString(rule) works well and returns:

{"ruleName":"rule1","steps":[{"stepIdentifer":"SI1"},{"stepIdentifer":"SI2"}]}

Also you can use other JSON libraries which are more convenient to use like spray-json or even circe which is based on functional paradigm

Duelist
  • 1,562
  • 1
  • 9
  • 24