【问题标题】:Jackson deserialize with GenericsJackson 使用泛型反序列化
【发布时间】:2016-11-12 09:52:23
【问题描述】:

我正在尝试将 json 反序列化为 scala 类,其中包含 Aclass、Bclass 或 Cclass 类型的集合

class Results[M](results:util.ArrayList[M]) {

  def getResults:util.ArrayList[M]=results

  def this() {
    this(new util.ArrayList())
  }
}

Json 看起来像:

{ "results":[{"a":1},{"a":1}]} 

{ "results":[{"b":1},{"b":1}]} 

{ "results":[{"b":1},{"b":1}]} 

这是我的对象映射器

  val mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

这里我如何反序列化类类型 Aclass 的 json

val results = mapper.readValue(json, classOf[Results[Aclass]])

问题在于,结果返回一个 ArrayList,其中每个元素都不是 Aclass 的一个实例,而是一个 LinkedHashMap

如果我将代码更改为使用泛型,我会在类型中明确说明

class Results[Aclass](results:util.ArrayList[Aclass]) {

  def getResults:util.ArrayList[Aclass]=results

  def this() {
    this(new util.ArrayList())
  }
}

它工作并返回一个带有 Aclass 元素数组结果的类。

我在这里做错了什么?我认为这是库中的错误

问候。

【问题讨论】:

  • 你是被 jackson 困住了,还是你也可以使用不基于反射的库(例如 circe 或 argonaut)?
  • 完全开放以使用新库,如果不需要太多代码并实现我想要的。但无论如何,我设法使用 TypeFactory 使其工作,但仍然不高兴我的解决方案看起来有多复杂

标签: scala jackson


【解决方案1】:

原因是java.lang.Class 不包含有关泛型参数的信息。 classOf[Result[Aclass]] 的值为 java.lang.Class。它没有关于类型参数Aclass 的信息。它只代表Results 类。

映射器会满足您的要求:为您提供 Results 的任何内容,以及最好的地图。

要解决它,请改用采用 JavaType 的 readValue 方法。 JavaType 可以使用TypeFactory 创建:

val results:Results[Aclass] = mapper.readValue(json, mapper.getTypeFactory()
        .constructParametricType(classOf[Results[_]], classOf[Aclass]))

【讨论】:

  • 似乎无法反序列化任何内容。 java.lang.ClassCastException:politrons.apple.search.model.Results 不能转换为 scala.runtime.Nothing$
  • 抱歉,忘记在 val 结果中添加类型声明。没有它,类型会被推断为 Nothing,这在运行时显然是不正确的。这是由于 readValue 方法的此重载的未绑定类型参数。我刚刚更新了答案。
  • 最后我得到了另一个解决方案,使用 Play json 但谢谢!
猜你喜欢
  • 2012-10-18
  • 2012-07-24
  • 1970-01-01
  • 2019-04-29
  • 2014-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多