【问题标题】:Jackson mapper with generic class in scala在 scala 中具有通用类的杰克逊映射器
【发布时间】:2015-06-30 15:29:30
【问题描述】:

我正在尝试序列化GeneralResponse:

case class GeneralResponse[T](succeeded: Boolean, payload: Option[T])

有效载荷是GroupsForUserResult:

case class GroupsForUserResult(groups: Seq[UUID]).

我正在使用mapper.readValue(response.body, classOf[GeneralResponse[GroupsForUserResult]]),但不幸的是,有效负载被序​​列化为Map,而不是所需的案例类(GroupForUserResult)。

【问题讨论】:

    标签: json scala serialization jackson case-class


    【解决方案1】:

    由于 Java 擦除 - Jackson 在运行时无法从行中知道泛型类型 T -

    mapper.readValue(response.body, classOf[GeneralResponse[GroupsForUserResult]])
    

    解决这个问题的方法是

    import com.fasterxml.jackson.core.`type`.TypeReference
    
    mapper.readValue(json, new TypeReference[GeneralResponse[GroupsForUserResult]] {})
    

    这样您就可以为TypeReference 的实例提供所有需要的类型信息。

    【讨论】:

    • 它在我的情况下不起作用。拥有case class InputMessage[+S<:Storage,+P<:Partitioning](fromView: View[S,P], toView: View[S,P], partition: Partition)ObjMapper.readValue[InputMessage[S3Storage, TimePartitioning]](inputMsg, new TypeReference[InputMessage[S3Storage, TimePartitioning]]() {}) 我仍然收到错误
    【解决方案2】:

    接受的答案足够接近,但您还必须向 .readValue 方法提供类型参数,

    带测试的工作示例,

    import com.fasterxml.jackson.core.`type`.TypeReference
    import com.fasterxml.jackson.databind.ObjectMapper
    import com.fasterxml.jackson.module.scala.DefaultScalaModule
    import org.scalatest.{FunSuite, Matchers}
    
    case class Customer[T](name: String, address: String, metadata: T)
    
    case class Privileged(desc: String)
    
    class ObjectMapperSpecs extends FunSuite with Matchers {
    
      test("deserialises to case class") {
    
        val objectMapper = new ObjectMapper()
          .registerModule(DefaultScalaModule)
    
        val value1 = new TypeReference[Customer[Privileged]] {}
    
        val response = objectMapper.readValue[Customer[Privileged]](
          """{
               "name": "prayagupd",
               "address": "myaddress",
               "metadata": { "desc" : "some description" }
             }
          """.stripMargin, new TypeReference[Customer[Privileged]] {})
    
        response.metadata.getClass shouldBe classOf[Privileged]
        response.metadata.desc shouldBe "some description"
      }
    
    }
    

    com.fasterxml.jackson.databind.ObjectMapper#readValue的签名,

    public <T> T readValue(String content, TypeReference valueTypeRef)
        throws IOException, JsonParseException, JsonMappingException
    {
        return (T) _readMapAndClose(_jsonFactory.createParser(content), _typeFactory.constructType(valueTypeRef));
    } 
    

    如果不提供 type 参数,会报错Customer cannot be cast to scala.runtime.Nothing$

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-22
      • 1970-01-01
      • 1970-01-01
      • 2013-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多