使用 Jackson 将 protobuf 转换为 JSON?

2022-09-03 10:05:25

在使用Jackson的ObjectMapper将原型buf转换为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

当我在现有代码库上工作时,我有以下约束:

  1. 我无法修改 MyObjectPb 的源代码,因此我无法在 MyObjectPb 中使用 Jackson 的忽略注释。
  2. 我也不能使用Gson的库来转换对象,因为代码库已经使用Jackson进行序列化。不建议添加新的依赖项。

如何告诉 Jackson 忽略(取消)序列化 MyObjectPb 中的 UnknownFieldSet 对象?


我已经尝试了以下方法,但这些方法似乎并不能解决问题:

a) 配置对象映射器:

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

当前(2018 年 10 月)序列化原型的方法是按以下方式使用:com.google.protobuf.util.JsonFormat

JsonFormat.printer().print(myMessageOrBuilder)

我在我的protobuf对象之前使用了注释,并添加了这个类:@JsonSerialize(using = MyMessageSerializer.class)

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));
    }
}

这允许将我的原型buf正确转换为JSON。new ObjectMapper().writeValueAsString(wrapperObject)


答案 2

我使用JsonFormat类(com.googlecode.protobuf.format.JsonFormat)来转换protobuf:

new JsonFormat().printToString(myObject)

这对我来说是完美的。