杰克逊(Jackson)注释混合在某些字段上不起作用 [英] Jackson annotation mixin on some of the fields doesn't work

查看:127
本文介绍了杰克逊(Jackson)注释混合在某些字段上不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'd like to deserialize json to the following class

  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中的错误(如

but due to a bug in jackson (as explained in FAQ),
the following code will fail:

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

有错误:

java.lang.Integer无法转换为java.lang.Long

java.lang.Integer cannot be cast to java.lang.Long

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

creating the following mixin solves that bug, and the code work as expected:

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:

Problem

In my case Target class contains a lot of fields, and only one of them needs an annotation.
therefore, I'd like to create the Mixin with only a single argument:

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

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

But when defining Mixin like this, the annotation seems to not be applied, and this code fails again:

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

有办法使它工作吗?

完整代码重新创建问题:

Full code to recreate the problem:

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))

推荐答案

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

The problem could be that your mixin doesn't actually declare any fields - only constructor. And constructor gets overridden by your case class. So what you can do is model your Mixin as a trait with the annotated getter:

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

 trait Mixin {
               @JsonDeserialize(contentAs = classOf[Long]) def a: Option[Long]
 }

这篇关于杰克逊(Jackson)注释混合在某些字段上不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆