使用Jackson将Protobuf转换为JSON?

时间:2018-07-30 07:15:35

标签: java json jackson protocol-buffers

在使用杰克逊的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

当我在现有代码库上工作时,我受到以下限制:

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

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


我尝试了以下方法,但是这些方法似乎无法解决问题:

a)配置ObjectMapper:

myObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
myObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

b)使用杰克逊混音:

@JsonIgnoreType
private abstract class UnknownFieldSetIgnoreMixIn {}

myObjectMapper.addMixIn(UnknownFieldSet.class, UnknownFieldSetIgnoreMixIn.class)

4 个答案:

答案 0 :(得分:3)

序列化protobuf的当前方法(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.writeString(JsonFormat.printer().print(message));
    }
}

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

答案 1 :(得分:2)

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

new JsonFormat().printToString(myObject)

这对我来说做得很好。

答案 2 :(得分:1)

包含内容已从com.googlecode.protobuf.format.JsonFormat更改 至 com.google.protobuf.util.JsonFormat

因此,如果您的protobuf依赖项缺少format软件包,请尝试在JsonFormat中寻找util

有了这个包含,您应该可以使用 java new JsonFormat().printToString(myObject) 如@ amad-person建议。

答案 3 :(得分:0)

您应该将com.google.protobuf.util.JsonFormat包中的以下类用作:

JsonFormat.printer().print()