I’m trying to write a method that will allow Jackson ObjectMapper readValue on a json string to a parameterized object type. Something like this
case class MyObj(field1: String, field2: String)
val objectMapper: ObjectMapper = new ObjectMapper().registerModule(new DefaultScalaModule)
def fromJson[T](jsonString: String, objTyp: T): T = {
objectMapper.readValue(jsonString, classOf[T])
}
val x = fromJson("""{"field1": "something", "field2": "something"}""", MyObj)
This of course returns an error of
class type required but T found
i’ve looked at this issue Scala classOf for type parameter
but it doesn’t seem to help. It seems like this is possible to do somehow. Looking for any help
2
Answers
You have to give it the actual runtime class to parse into, not just a type parameter.
One way to do it is passing the class directly:
Alternatively, you can use
ClassTag
, which looks a bit messier in implementation, but kinda prettier at call site:In the very first answer there it’s written
classTag[T].runtimeClass
as a replacement ofclassOf[T]
. This should help.Regarding the signature
You should notice that
MyObj
has typeMyObj.type
(companion-object type), notMyObj
(case-class type).Class companion object vs. case class itself
So if you call
fromJson("""...""", MyObj)
then the types in these two placescan’t be the same.
If it’s enough for you to call
or
(normally it should be enough) then please see @Dima’s answer, you should prefer those options, they’re easier.
Just in case, if you really want to call like
fromJson("""...""", MyObj)
then for example you can use the type classToCompanion
(this is more complicated) fromInvoke construcotr based on passed parameter
Get companion object of class by given generic type Scala (answer)