3

コンテキストとして、ほとんどのデータをJSON文字列として保存しています。これは、バックエンドのHadoopで非常にうまく機能し、フロントエンドのRubyで簡単に処理できます。私のデータ型は、継承の自然なパターンに適合しています。

簡単にするために、クラスPetと、ペットに餌を与えるプロセスFeedPetがあるとします。また、ペットの一種であるDogにのみ適用されるWalkDogプロセスもあります。私のデータは、犬ではないペットを歩こうとすることを心配する必要がないように編成されています。

私がやりたいのは、PetとDogがPetを拡張し、Dogに追加のメソッド「getLeash()」があることですが、これをJSONにマップする方法がわかりません。

代わりに、種データハッシュマップを持つクラスPetがあるため、WalkDogプロセスはdog.getLeash()ではなくpet.getSpeciesData( "leash")を呼び出します。

Dog extends Petを作成し、Jacksonライブラリを使用してそれをJSONにシリアル化できます。JSONオブジェクトにはリーシュフィールドがあります。しかし、私がすべてのペットに餌を与えたいと仮定します。すべてのペットにはgetFood()メソッドがあります。したがって、FeedPetプロセスはオブジェクトをPetに逆シリアル化します。しかし、これはリーシュフィールドを失います。

WalkDogプロセスは、すべての入力がDogsになることを認識しているため、これを実行できます。これにより、WalkDogプロセスは、Dogとして読み取り、Dogとして書き戻すことができます。

タイプを保持できるようにJavaオブジェクトをJSONにシリアル化する方法はありますか?Railsの単一テーブル継承のようなものを考えていますが、JSONライブラリが理解できるものでなければなりません。

4

2 に答える 2

2

それを機能させるには、いくつかのオブジェクト型情報をデータに埋め込む必要があり (デシリアライズにのみ役立つ場合)、通常は必要のない外部スキーマ定義を使用する必要があります (xml の XML スキーマなど。基本的にはジェネリック型システムであるため)。 . これには、ORM と同じ問題があります。Hibernate は醜い回避策 (n+1 - 結合、「スーパー テーブル」、または識別子フィールド) を使用する必要があります。

別の言い方をすれば、データ マッピング/バインドは、オブジェクトのシリアル化/逆シリアル化とまったく同じではありません (後者は、オブジェクトのアイデンティティをより多く保持しようとします)。

ここでは、基本的に次のようなものが必要であると想定しています。

Pet pet = mapper.readValue(jsonString, Pet.class);
// (and possibly get an exception if Pet is an abstract class...)
Leash l = ((Dog) pet).getLeash();

そうでない場合は、単純に Dog にバインドできます。

Dog dog = mapper.readValue(jsonString, Dog.class);

とにかく:ジャクソンプロジェクトには、これを行うための機能リクエストがあります。これにより、(私が思うに)やりたいことを実行できます。

ただし、JSON 内でオブジェクト型情報を渡す標準的な方法がないため、このソリューションはほとんど Java で機能します。XML では、これは XML スキーマで定義された "xsi:type" 属性を使用して行うことができます。これはスキーマ型を識別し、クラスにマップされます (はい、かなり複雑な方法ですが、機能します)。

UPDATE : Jackson 1.5では、これに対するサポートが追加されました (つまり、実装された JACKSON-91 機能要求)。そのため、型識別子の生成に使用して、ポリモーフィック型を適切に処理できます。型情報を含める方法の詳細を完全に構成できることを考えると、Java 以外のシステムでも動作するはずです。Java クラス名の使用に限定されません。

于 2009-04-08T20:26:23.080 に答える
0

django のフィクスチャ以外で JSON を使用した経験はあまりありませんが、その場合、関連付けられた値を持つ「モデル」キーしかありません。

次に、オブジェクトを解釈してその型と継承階層を決定するのは、プログラム次第です。

私が言おうとしているのは、これはシリアル化する必要がないため、利用可能なメソッドは関係ないということです。オブジェクトの名前と属性のみ。

- アップデート

質問をもう一度読んだ後、プロセスが実際のクラスではなく、親クラスに逆シリアル化されているようです。あなたの犬のクラスはペットを継承しているので、デシリアライザーが最も特化したクラスのオブジェクトを作成していることを確認したいだけです.

Jackson ライブラリについてはわかりませんが、モデル フィールドのタイプを設定できる場合は、それでよいかもしれません。

于 2009-04-08T00:24:27.200 に答える