2020年2月7日JSONを使ってクライアント・サーバ間の通信を行ったり、データ永続化したりする場合に必ず困るはめになることが「JSONは継承を扱えない」点である。以下のようなクラス構造があり、FooもBarもTopとして扱いたい。(Foo)jsonからデシリアライズしてFooに戻す。このような操作はそのままではできない。JSON化した時に「どのクラスをシリアライズしたものなのか」という情報が入らないからである。ContentsJSON化文字列に元クラスの目印を入れるさらに下位クラスのある場合JAX-RSで使用する場合JSON化文字列に元クラスの目印を入れるここではJacksonのアノテーションによる例を見てみる。Jacksonには対象クラスにアノテーションせずとも、これを行う機能があるのだが、ここでは都合上アノテーションによるもののみとする。}}見ての通り、Fooをシリアライズした後、デシリアライズすればFooに戻り、Barについても同じである。ここでのミソとしては、シリアライズ後のJSON文字列に付加されている「”@type”:”F”」あるいは「”@type”:”B”」という部分である。この部分で、実際にシリアライズされたのがFooなのかBarなのかを区別している。これを付加する指示を行っているのが、Topにつけられたアノテーションだ。}見ての通り、Fooの場合は”F”、Barの場合は”B”としている。このやり方の他に、実際のFull-Qualifiedクラス名称をJSON中に入れ込んでしまう方法等もあるが、やめた方が無難だろう。クラス名称やパッケージ名称を変更できなくなるからだ。他のオプションとして、JsonTypeInfoに指定できるものとしてはpropertyがある。property=”@”)」などと指定すると、{"@":"F","a":123,"b":456}となる。このように、クラス区別項目(?)の名称を指定できる。他にincludeというプロパティがあり、これは以下のように指定する。include=As.PROPERTY)デフォルトは、As.PROPETYだが、これをAs.EXTERNAL_PROPERTYとしても、この例では変化が見られなかった。As.WRAPPER_OBJECTにすると、property値は無視され、以下になる。{"F":{"a":123,"b":456}}As.WRAPPER_ARRAYにすると、これもproperty値は無視され、以下になる。["F",{"a":123,"b":456}]As.EXISTING_PROPERTYにすると、なぜかクラス選択情報が消えてしまう。何のためにあるのか不明。{"a":123,"b":456}これらの動作の違いというのは、おそらくJacksonを使用していない・できないシステムとのデータ交換のためだろう。個人的に最も無難と思われるのは、WRAPPER_OBJECTのような気がする。Jackson側はWRAPPER_OBJECTにしておき、Jacksonのような「継承」を使えないシステム側では、以下のような定義にしておけば良いかと思われる。B;}さらに下位クラスのある場合さらに下位クラスのある場合でもトップにそれを記述してやれば良いようだ。}}JAX-RSで使用する場合なぜかJAX-RSでこれを使用した場合に正しくシリアライズ・デシリアライズされないことがあるようだ。原因は全くわかっていない。}シリアライズ後のJSONには正しく「クラス種類マーカー」がつかないケースがある(ついてるケースもある)。}とすると、送信側からは正しく「クラス種類マーカー」がついているのに、正しくデシリアライズできないケースがあった。この場合には、Listをラップするクラスを作る解決策しか現在のところ思いつかない。ofデータの仕様を変更したために、正しくデシリアライズできない事例が発生した。言い方が難しいのだが、やりたいことはこういうことだ。コメントをキャンセルメールアドレスが公開されることはありません。*ウェブサイト上に表示された文字を入力してください。