シリアル化されたときに、そのメンバーの 1 つを代わりにシリアル化する必要があるクラスがあります。私のクラスは:
@JsonSerialize(using = MyClassSerializer.class)
public class MyClass implements Serializable {
/**
* A default ID for this class for serialization.
*/
private static final long serialVersionUID = 1L;
/**
* A member of this object.
*/
private final OtherClass otherClass;
...
/**
* Returns the instance of the member object.
*
* @return The instance of the member object.
*/
public OtherClass getOtherClass() {
return otherClass;
}
}
これを実現するために、非常に単純なカスタム シリアライザーを作成しました。
public class MyClassSerializer extends JsonSerializer<MyClass> {
/**
* Serializes only the OtherClass field.
*/
@Override
public void serialize(
final MyClass myClass,
final JsonGenerator generator,
final SerializerProvider provider)
throws IOException, JsonProcessingException {
// Write the schema.
generator.writeObject(myClass.getOtherClass());
}
}
これは、このようなことを行うための最も簡単な (そして、最も正しいと私が信じている) 方法です。そうしたかったとしても、OtherClass は抽象ルート クラスであるため、カスタム シリアライザーを作成するのは非常に複雑です。ただし、これは、いくつかの注釈を付けることで、Jackson を介して実現できます。
@JsonTypeInfo(
use = Id.NAME,
include = As.PROPERTY,
property = OtherClass.JSON_KEY_TYPE,
defaultImpl = OtherClassDefault.class)
@JsonSubTypes({
@JsonSubTypes.Type(
value = SubOtherClass1.class,
name = SubOtherClass1.TYPE_ID),
@JsonSubTypes.Type(
value = SubOtherClass2.class,
name = SubOtherClass2.TYPE_ID),
@JsonSubTypes.Type(
value = SubOtherClass3.class,
name = SubOtherClass3.TYPE_ID),
@JsonSubTypes.Type(
value = SubOtherClass4.class,
name = SubOtherClass4.TYPE_ID),
@JsonSubTypes.Type(
value = SubOtherClass5.class,
name = SubOtherClass5.TYPE_ID) })
@JsonAutoDetect(
fieldVisibility = Visibility.DEFAULT,
getterVisibility = Visibility.NONE,
setterVisibility = Visibility.NONE,
creatorVisibility = Visibility.DEFAULT)
public abstract class OtherClass implements Serializable {
...
}
Jackson を使用してこれをテストし、MyClass のインスタンスをシリアル化および逆シリアル化しましたが、意図したとおりに動作します。
私のアプリケーション コードはもう少し複雑です。ContainerClass
type のメンバーを持つ がありますMyClass
。ContainerClass
MongoJack を使用してのインスタンスをシリアル化しようとしています。
// Get the authentication token collection.
JacksonDBCollection<ContainerClass, Object> collection =
JacksonDBCollection
.wrap(
MongoBinController
.getInstance()
.getDb()
.getCollection(COLLECTION_NAME),
ContainerClass.class);
// Save it.
collection.insert(container);
ただし、次のエラーが表示されます。
...
Caused by: java.lang.IllegalArgumentException: can't serialize class my.package.MyClass
at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:270)
...
@JsonSerialize
fromを削除すると機能するようになりますが、これによりインスタンスMyClass
全体がシリアル化され、これは私が望むものではありません。MyClass
これにより、問題がカスタム シリアライザーにあることがほぼ確実になりますが、他にどのように記述すればよいかわかりません。
前もって感謝します。