web-dev-qa-db-ja.com

Jackson JSONジェネレーターを使用して、複数のオブジェクトを1つのフィールドに書き込むにはどうすればよいですか?

次の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_の各フィールドを個別に書き込むことです。多くのフィールドを持つ巨大なクラスでソリューションを使用したいので、これを必要としないソリューションを探しています。

11
CFL_Jeff

「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機能を有効にする必要があります。 シリアル化機能 を参照してください)

11
Alex Vayda