某些字段上的 Jackson 注释混合不起作用
Jackson annotation mixin on some of the fields doesn't work
前言
我想将 json 反序列化为以下 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 中的错误(如 FAQ 中所述),
以下代码将失败:
println(res.a.map(_ + 1))
错误:
java.lang.Integer cannot be cast to 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
class 包含很多字段,只有其中一个需要注释。
因此,我想创建只有一个参数的 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))
问题可能是您的 mixin 实际上没有声明任何字段 - 只有构造函数。并且构造函数被您的案例覆盖 class。
所以你可以做的是将你的 Mixin 建模为带有注释的特征 getter:
case class Target(
a: Option[Long],
b: String
)
trait Mixin {
@JsonDeserialize(contentAs = classOf[Long]) def a: Option[Long]
}
前言
我想将 json 反序列化为以下 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 中的错误(如 FAQ 中所述),
以下代码将失败:
println(res.a.map(_ + 1))
错误:
java.lang.Integer cannot be cast to 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
class 包含很多字段,只有其中一个需要注释。
因此,我想创建只有一个参数的 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))
问题可能是您的 mixin 实际上没有声明任何字段 - 只有构造函数。并且构造函数被您的案例覆盖 class。 所以你可以做的是将你的 Mixin 建模为带有注释的特征 getter:
case class Target(
a: Option[Long],
b: String
)
trait Mixin {
@JsonDeserialize(contentAs = classOf[Long]) def a: Option[Long]
}