Jackson の ObjectMapper を使用して protobuf を JSON に変換しているときに、次のエラーが発生します。
com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Direct self-reference leading to cycle (through reference chain:
MyObjectPb$MyObject["unknownFields"]->
com.google.protobuf.UnknownFieldSet["defaultInstanceForType"])
MyObjectPb には次のフィールドがあります。
protected com.google.protobuf.UnknownFieldSet unknownFields
既存のコードベースで作業しているため、次のような制約があります。
- MyObjectPb のソース コードを変更できないため、MyObjectPb で Jackson の ignore アノテーションを使用できません。
- コードベースではすでにシリアル化に Jackson を使用しているため、Gson のライブラリを使用してオブジェクトを変換することもできません。新しい依存関係を追加することはお勧めしません。
MyObjectPb 内の UnknownFieldSet オブジェクトのシリアル化 (デシリアル化) を無視するように Jackson に指示するにはどうすればよいですか?
以下のことを試してみましたが、これらの方法では問題は解決されないようです。
a) ObjectMapper の構成:
myObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
myObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
b) Jackson Mixin を使用する:
@JsonIgnoreType
private abstract class UnknownFieldSetIgnoreMixIn {}
myObjectMapper.addMixIn(UnknownFieldSet.class, UnknownFieldSetIgnoreMixIn.class)
ベストアンサー1
protobuf をシリアル化する現在の方法 (2018 年 10 月) は、com.google.protobuf.util.JsonFormat
次の方法を使用することです。
JsonFormat.printer().print(myMessageOrBuilder)
@JsonSerialize(using = MyMessageSerializer.class)
protobuf オブジェクトの直前にアノテーションを使用し、次のクラスを追加しました。
public static class MyMessageSerializer extends JsonSerializer<Message> {
@Override
public void serialize(Message message, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeRawValue(JsonFormat.printer().print(message));
}
}
これにより、new ObjectMapper().writeValueAsString(wrapperObject)
protobuf を JSON に適切に変換できるようになりました。