0

I am not sure if this is achievable and I have a very basic understanding of how generics work in scala. But I was wondering if this is possible. Say I have a method:

case class Person(id:String,name:String)
case class Student(id:String,name:String, class:String)

    def convertToJson[A](fileName:String):{
     //read file
     parse[A]
    }

Is it possible to write this generic method which would parse the json based on the type of class I send when I call the convertToJson method? Something like:

convertToJson[Student](fileName)
convertToJson[Person](fileName)

BTW the above code gives me a :

No Manifest available for A. error.

Using json4s for parsing. Any help is appreciated.

Achilleus
  • 1,824
  • 3
  • 20
  • 40

1 Answers1

3

This will convert a JSON string to a case class

import org.json4s._
import org.json4s.jackson.JsonMethods._

def convertToJson[T](json: String)(implicit fmt: Formats = DefaultFormats, mf: Manifest[T]): T =
  Extraction.extract(parse(json))

Once this is defined you can parse appropriate strings to the required type:

case class Person(id: String, name: String)
case class Student(id: String, name: String, `class`: String)

val person = convertToJson[Person]("""{"name":"Jane","id":45}""")
val student = convertToJson[Student]("""{"name":"John","id":63, "class": "101"}""")

Note that this will ignore JSON data that does not match fields in the case class. If a field is optional in the JSON, make it an Option in the case class and you will get None if the field is not there.

Tim
  • 26,753
  • 2
  • 16
  • 29
  • That worked! Thanks. On a side note is there a way to deal with nulling out case when we have bad data? Say throw an exception or something? – Achilleus Mar 26 '19 at 19:52
  • @Achilleus If you have bad data the `extract` will throw an exception. You can let the caller handle that, or wrap the `extract` call in a `Try` and return a `Try[T]`, which is perhaps more standard in Scala. – Tim Mar 26 '19 at 23:27
  • Actually, it won't throw an exception in the situation when we are dealing with nested json and an object in it say has a field spelled wrong. It will just null that object and move on. I was wondering if we can somehow specify it to fail or throw an exception instead of nulling it out. – Achilleus Mar 26 '19 at 23:37
  • Can you give an example of this? If I rename one of the fields from the JSON string I get `MappingException: No usable value for `. – Tim Mar 26 '19 at 23:50
  • Ah actually, it throws the exception for case classes. But I am using an Avro specific record case class. Its a case class that extends org.apache.avro.specific.SpecificRecordBase. But somehow it serializes to null in this case. – Achilleus Mar 27 '19 at 16:05
  • Posted another question here https://stackoverflow.com/questions/55381927/json4s-serialization-of-string-to-avro-specific-record-class – Achilleus Mar 27 '19 at 16:16
  • is the `Manifest[T]` actually needed? – mljohns89 Sep 09 '22 at 16:57