1
I'va多くの具体的なタイプで実現することができるOIDインタフェース:ジャクソンの多型シリアライズ/デシリアライゼーションのカスタムシリアライザ/デシリアライザ
public interface OID {
}
public abstract class OIDBase
implements OID {
private String _id;
}
public class MyOID
extends OIDBase {
public MyOID() {
// default no-args constructor
}
}
public class MyOtherOID
extends OIDBase {
public MyOtherOID() {
// default no-args constructor
}
}
今、私は2つのフィールドを持つオブジェクトをした、1抽象を使用して定義インターフェイスタイプ(OID)と他のコンクリートの種類(筋様)を使用して定義
public class MyBean {
private OID _absOid;
private MyOID _concreteOid;
public MyBean(final OID absOid,final MyOID concreteOid) {
_absOid = absOid;
_concreteOid = concreteOid;
}
}
私は抽象インタフェース型やコンクリート型を使用して、それらが定義されているかどうかを、異なるフィールドをデシリアライズ/シリアライズするジャクソンを使用します:
{
"_absOid": {
"type" : "MyOtherOID",
"id" : "__an_id__"
},
"_concreteOid" : "__another_id___"
}
_absOid
は型情報(多型シリアライズ)と_concreteOid
などのシリアル化されていることに注意してくださいそうするために、テキスト
としてシリアル化されて、私はとOIDインタフェースを注釈を付けました:
@JsonSubTypes({
@JsonSubTypes.Type(MyOID.class),
@JsonSubTypes.Type(MyOtherOID.class)
})
public interface OID {
}
と割り当て各コンクリートタイプのタイプID:
@JsonTypeName("MyOID")
public class MyOID
extends OIDBase {
...
}
@JsonTypeName("MyOtherOID")
public class MyOtherOID
extends OIDBase {
...
}
public class MyBean {
@JsonTypeInfo(include = JsonTypeInfo.As.PROPERTY,
use = JsonTypeInfo.Id.NAME,
property = "type")
private OID _absOid;
private MyOID _concreteOid;
}
これまでのところ、とても良いが、フィールドは抽象型(OIDを使用して定義されている場合、異なるシリアル化するために:最後に、コンテナ豆の抽象的な定義フィールドは、ジャクソンは型情報を含める作るために注釈を付けています)とフィールドは、具体的なタイプ(筋様)を使用して定義されている場合、私は、カスタム・シリアライザを作成する必要があります。
まずシリアライザ/デシリアライザを使用するために、具体的なタイプに注釈を付ける:
@JsonTypeName("MyOID")
@JsonSerialize(using=OIDSerializer.class) @JsonDeserialize(using=OIDDeSerializer.class)
public class MyOID
extends OIDBase {
...
}
@JsonTypeName("MyOtherOID")
@JsonSerialize(using=OIDSerializer.class) @JsonDeserialize(using=OIDDeSerializer.class)
public class MyOtherOID
extends OIDBase {
...
}
...シリアライザ/デシリアライザコード:
public static class OIDSerializer
extends JsonSerializer<OID> {
@Override
public void serialize(final OID value,
final JsonGenerator jgen,
final SerializerProvider provider) throws IOException,JsonProcessingException {
// **** used when serializing a concrete type
jgen.writeString(value.toString());
}
@Override
public void serializeWithType(final OID value,
final JsonGenerator jgen,
final SerializerProvider provider,
final TypeSerializer typeSer) throws IOException {
// **** used when serializing a polymorphic type
// guess the type id
WritableTypeId typeId = typeSer.typeId(value,JsonToken.START_OBJECT);
// type prefix
typeSer.writeTypePrefix(jgen,
typeId);
// object
jgen.writeFieldName("id");
jgen.writeString(value.toString());
// type suffix
typeId.wrapperWritten = !jgen.canWriteTypeId();
typeSer.writeTypeSuffix(jgen,
typeId);
}
}
デシリアライズするときPROBLEMは JSON文字列をを発生し、私は次のカスタムデシリアライザを使用しました:
public static class OIDDeSerializer
extends StdDeserializer<OID> {
public MyOIDDeSerializer() {
super(MyOID.class);
}
@Override
public OID deserialize(final JsonParser jp,
final DeserializationContext ctxt) throws IOException,JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
// [1] - Read the id depending on the serialized format
String oidStr = null;
// text node > concrete oid impl serialized as [value]
if (node.getNodeType() == JsonNodeType.STRING) {
oidStr = ((TextNode)node).asText();
}
// oid=value > abstract oid impl serialized as {typeId=[type],oid={value]}
else {
ObjectNode objNode = (ObjectNode)node;
oidStr = objNode.findValue("id").asText();
}
// [2] - Read tye type id
String typeId = objNode.findValue("type").asText()
// PROBLEM!!!!!!
// how get the type from the typeId in order to create the concrete instance
// how access the type resolver????
Class<? extends OID> oidType = RESOLVE TYPE FROM THE ID
return oidType.newInstance();
}
}
ので問題は、型にアクセスする方法をですタイプID解決からカスタムデシリアライザ ???
私はジャクソンには専門家だが、私はおそらく、次のいずれかを試してみた:1.試しOID' '上の注釈を読んで、id型に一致する注釈からクラスを取得するか、2 。型IDを使用する代わりに、完全修飾クラス名を使用しようとしていました。シリアライズすると、単純な 'Cl ass.forName(fqcn) '。 - おそらく、あなたはあなた自身で注釈をスキャンすることなく、変種1をやる方法を探していますか? – Thomas
ありがとう@トーマス、ソリューションに問題があります。問題はアノテーションにアクセスする方法です。info:sachinが指摘しているように、Jacksonは注釈イントロスペクターを使用しています。 – futuretelematics