web-dev-qa-db-fra.com

Convertir un protobuf en JSON en utilisant Jackson?

J'obtiens l'erreur suivante lors de la conversion d'un protobuf en JSON à l'aide de l'ObjectMapper de Jackson:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
Direct self-reference leading to cycle (through reference chain:
MyObjectPb$MyObject["unknownFields"]->
com.google.protobuf.UnknownFieldSet["defaultInstanceForType"])

MyObjectPb a le champ suivant:

protected com.google.protobuf.UnknownFieldSet unknownFields

Comme je travaille sur une base de code existante, j'ai les contraintes suivantes:

  1. Je ne peux pas modifier le code source de MyObjectPb, donc je ne peux pas utiliser les annotations ignorées de Jackson dans MyObjectPb.
  2. Je ne peux pas non plus utiliser les bibliothèques de Gson pour convertir l'objet, car la base de code utilise déjà Jackson pour la sérialisation. L'ajout d'une nouvelle dépendance n'est pas recommandé.

Comment dire à Jackson d'ignorer (dé) sérialiser l'objet UnknownFieldSet dans MyObjectPb?


J'ai essayé ce qui suit, mais ces approches ne semblent pas résoudre le problème:

a) Configuration de l'ObjectMapper:

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

b) Utilisation d'un Jackson Mixin:

@JsonIgnoreType
private abstract class UnknownFieldSetIgnoreMixIn {}

myObjectMapper.addMixIn(UnknownFieldSet.class, UnknownFieldSetIgnoreMixIn.class)
6
amad-person

J'ai utilisé la classe JsonFormat (com.googlecode.protobuf.format.JsonFormat) pour convertir le protobuf:

new JsonFormat().printToString(myObject)

Cela a parfaitement fonctionné pour moi.

5
amad-person

La façon actuelle (octobre 2018) de sérialiser un protobuf est d'utiliser com.google.protobuf.util.JsonFormat De la manière suivante:

JsonFormat.printer().print(myMessageOrBuilder)

J'ai utilisé l'annotation @JsonSerialize(using = MyMessageSerializer.class) juste avant mon objet protobuf et j'ai ajouté cette classe:

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

Cela a permis à new ObjectMapper().writeValueAsString(wrapperObject) de convertir correctement mon protobuf en JSON.

5
M H Chu

L'inclusion est passée de com.googlecode.protobuf.format.JsonFormat À com.google.protobuf.util.JsonFormat

Donc, si votre dépendance protobuf manque le package format, essayez de rechercher JsonFormat dans util.

Avec ceci include, vous devriez pouvoir utiliser Java new JsonFormat().printToString(myObject) comme @ amad-person l'a suggéré.

3
kykrueger