次の3つのクラスがあると仮定します(簡潔にするために、getterとsetterは省略しています)。
_@JsonAutoDetect
public class InfoCollection{
private InfoType1 info1;
private InfoType2 info2;
}
@JsonAutoDetect
public class InfoType1{
private String fieldA;
}
@JsonAutoDetect
public class InfoType2{
private String fieldB;
}
_
次の形式でInfoCollection
オブジェクトをシリアル化するJsonSerializer.serialize()
関数を記述しようとしています。
_{
"allInfo":{
"fieldA":"foo",
"fieldB":"bar"
}
}
_
これは私が今持っているものです:
_jsonGenerator.writeStartObject();
jsonGenerator.writeFieldName("allInfo");
jsonGenerator.writeObject(myInfoCollection.getInfo1());
jsonGenerator.writeObject(myInfoCollection.getInfo2());
jsonGenerator.writeEndObject();
_
これにより、次の例外が発生します。
_ org.codehaus.jackson.JsonGenerationException: Can not start an object, expecting field name
_
私は小さなものを見逃しているのですか、それとも完全に間違った方法でやっていますか?
注:これまでに提案されたいくつかの解決策は、_InfoType1
_および_InfoType2
_の各フィールドを個別に書き込むことです。多くのフィールドを持つ巨大なクラスでソリューションを使用したいので、これを必要としないソリューションを探しています。
「allInfo」は別のJSONオブジェクトであるため、writeFieldName("allInfo")
を呼び出す代わりにwriteObjectFieldStart("allInfo")
を呼び出す必要があります。したがって、カスタムシリアライザーは次のようになります。
public void serialize(InfoCollection infoCollection, JsonGenerator jgen, SerializerProvider provider) throws IOException{
jgen.writeStartObject();
jgen.writeObjectFieldStart("allInfo");
jgen.writeObjectField("fieldA", infoCollection.getInfo1().getFieldA());
jgen.writeObjectField("fieldB", infoCollection.getInfo2().getFieldB());
jgen.writeEndObject();
jgen.writeEndObject();
}
または、アノテーションベースのアプローチを試すこともできます。
@JsonRootName("allInfo")
public class InfoCollection {
@JsonUnwrapped
private InfoType1 info1;
@JsonUnwrapped
private InfoType2 info2;
/* getters, setters */
}
(これを機能させるには、SerializationConfig.Feature.WRAP_ROOT_VALUE
機能を有効にする必要があります。 シリアル化機能 を参照してください)