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}

または他のサブクラスですが、ジャークソンは常に私にまっすぐなものを返します.

また、Things がシリアル化されると、@type が含まれないため、クライアントが相手側で正しいタイプのオブジェクトをインスタンス化できなくなります。

実質的にまったく同じコードが、Jackson で Java EE サーバーの下で正常に機能することに注意してください。ジャクソンのさらに古いバージョン。

(私は、Java EE からすべての Scala & Play への移行を正当化しようとしています。ほとんどの場合、それは素晴らしいものになりましたが、このようなことを機能させる必要があります。自分たちで処理しなければならないのは本当に残念です。ポリモーフィックな JSON シリアライゼーション - これを行う方法があるはずですが、簡単に見つけることができません.Jackson は Jackson であるため、なぜこれがうまくいかないのか不思議です.)

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 を使用していないことに気づきました。Json の読み取り/書き込みが利用する適用/非適用の代わりに、引数なしの ctor が必要になる場合。

不変オブジェクトが困難または不可能になるため、このメカニズムを使用したくありません。そのため、Play の JSON ライブラリを直接使用してポリモーフィック JSON デシリアライゼーションを実現する方法を誰かが私に示してくれることを感謝します。

于 2013-08-03T14:48:48.150 に答える