0

这里非常简单的场景。我有:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@type")
class Thing(val id: Int) 

...

class LowerThing(id: Int) extends Thing(id) 

(我为这两个类定义了 Json.read 和 Json.writes,以及必要的应用/取消应用方法(它们做简单的事情 - 就像它们是案例类一样。)

在控制器中,在帖子中我有:

    request =>
      val thing = request.body.asJson.get.as[Thing]

我可以像这样发布 JSON:

{"@type":"com.foo.LowerThing","id":1}

或任何其他子类,但杰克森总是给我一个直截了当的东西。

此外,当事物被序列化时,@type 不包括在内,使得客户端无法在另一端实例化正确类型的对象。

请注意,几乎完全相同的代码可以在 Java EE 服务器下与 Jackson 一起正常工作。甚至更旧版本的杰克逊。

(我试图证明从 Java EE 迁移到全 Scala 和 Play 是合理的。在大多数情况下,它已经变得很棒,但是必须使这样的事情起作用。我们不得不自己处理这件事真的很可惜多态 JSON 序列化 - 必须有一种方法可以做到这一点,但我不容易找到它。而且我很困惑为什么这不能简单地工作,因为杰克逊是杰克逊。)

4

1 回答 1

0

好吧,我可以通过直接使用 Jackson API 来解决这个问题:

  val mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY)
  mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false)
  val thing = mapper.readValue(request.body.asJson.get.toString, classOf[Thing])

让我感到震惊的是,Play 的 JSON 库可能没有以我熟悉的方式使用 Jackson - 如果它们是无参数的 ctor 将是必要的,而不是 Json 读/写使用的应用/取消应用。

我不想使用这种机制,因为使不可变对象变得困难或不可能,所以我仍然希望有人向我展示如何直接使用 Play 的 JSON 库来实现多态 JSON 反序列化。

于 2013-08-03T14:48:48.150 回答