0

前言

我想将json反序列化为以下类

  case class Target(
    a: Option[Long],
    b: String
  )

使用以下代码:

val mapper = new ObjectMapper()
  .registerModule(DefaultScalaModule)

val req =
  """{
    |  "a": 123,
    |  "b": "xyz"
    |}
  """.stripMargin
val res = mapper.readValue(req, classOf[Target])

但由于 jackson 中的错误(如常见问题解答中所述),
以下代码将失败:

println(res.a.map(_ + 1))

有错误:

java.lang.Integer 不能转换为 java.lang.Long

创建以下 mixin 解决了该错误,并且代码按预期工作:

class Mixin(
        @JsonDeserialize(contentAs = classOf[Long]) a: Option[Long],
        b: String
           )

val mapper = new ObjectMapper()
   .registerModule(DefaultScalaModule)
   .addMixIn(classOf[Target], classOf[Mixin])

val res = mapper.readValue(req, classOf[Target])
println(res.a.map(_ + 1))

问题

在我的案例Target中,类包含很多字段,其中只有一个需要注释。
因此,我想Mixin只用一个参数来创建:

class Mixin(
        @JsonDeserialize(contentAs = classOf[Long]) a: Option[Long]
           )

但是当Mixin这样定义时,注释似乎没有应用,并且这段代码再次失败:

println(res.a.map(_ + 1))

有没有办法让它工作?


重现问题的完整代码:

case class Target(
                   a: Option[Long],
                   b: String
                 )
class Mixin(
             @JsonDeserialize(contentAs = classOf[Long]) a: Option[Long]
//             , b: String  //<--- uncommenting this line will fix the code
           )
val mapper = new ObjectMapper()
  .registerModule(DefaultScalaModule)
  .addMixIn(classOf[Target], classOf[Mixin])
val req =
  """{
    |  "a": 123,
    |  "b": "xyz"
    |}
  """.stripMargin
val res = mapper.readValue(req, classOf[Target])
println(res.a.map(_ + 1))
4

1 回答 1

1

问题可能是您的 mixin 实际上并没有声明任何字段 - 只有构造函数。并且构造函数被您的案例类覆盖。因此,您可以做的是使用带注释的 getter 将您的 Mixin 建模为特征:

 case class Target(
               a: Option[Long],
               b: String
             )

 trait Mixin {
               @JsonDeserialize(contentAs = classOf[Long]) def a: Option[Long]
 }
于 2018-08-21T03:39:07.887 回答