Enviando protobuf como JSON en primavera-arranque

Jan Blažek:

Estoy usando protobufs con esta definición concreta.

message Hash {
    string category = 1;
    repeated KVPair content = 2;
}

message KVPair {
    string key = 1;
    string value = 2;
}

Quiero enviar esto como JSON con mi solicitud de primavera-arranque. He añadido este paquete a mis dependencias Gradle:

compile group: 'com.google.protobuf', name: 'protobuf-java', version: '3.6.1'

Cuando trato de hash de salida objeto generado con este código:

@RestController
@RequestMapping("/api/crm/")
public class KVController {

    private final KVService kvService;

    public KVController(KVService kvService) {
        this.kvService = kvService;
    }

    @GetMapping("kv/{category}")
    public Hash getHash(@PathVariable String category) {
        Hash hash = kvService.retrieve(category);
        return hash;
    }
}

Se lanza esta excepción definitiva:

Causado por: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: autorreferencia directa que conduce a ciclo (a través de la cadena de referencia: com.blaazha.crm.proto.Hash [ "unknownFields"] -> com.google.protobuf.UnknownFieldSet [ "defaultInstanceForType"]) en com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from (InvalidDefinitionException.java:77) ~ [Jackson-databind-2.9.6.jar: 2.9.6] en com.fasterxml.jackson. databind.SerializerProvider.reportBadDefinition (SerializerProvider.java:1191) ~ [Jackson-databind-2.9.6.jar: 2.9.6] en com.fasterxml.jackson.databind.ser.BeanPropertyWriter._handleSelfReference (BeanPropertyWriter.java:944) ~ [Jackson-databind-2.9.6.jar: 2.9.6] en com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField (BeanPropertyWriter.java:721) ~ [Jackson-databind-2.9.6.jar: 2,9. 6] en com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields (BeanSerializerBase.java:719) ~ [Jackson-databind-2.9.6.jar: 2.9.6] en com.fasterxml.jackson.databind.ser.BeanSerializer.serialize (BeanSerializer.java : 155) ~ [Jackson-databind-2.9.6.jar: 2.9.6] en com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField (BeanPropertyWriter.java:727) ~ [Jackson-databind-2.9.6. jar: 2.9.6] en com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields (BeanSerializerBase.java:719) ~ [Jackson-databind-2.9.6.jar: 2.9.6] en com.fasterxml. jackson.databind.ser.BeanSerializer.serialize (BeanSerializer.java:155) ~ [Jackson-databind-2.9.6.jar: 2.9.6] en com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize (DefaultSerializerProvider.java : 480) ~ [Jackson-databind-2.9.6.jar: 2.9.6] en com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue (DefaultSerializerProvider.java:319) ~ [Jackson-databind-2.9.6.jar: 2.9.6] en com.fasterxml.jackson.databind.ObjectWriter $ Prefetch.serialize (ObjectWriter.java:1396) ~ [Jackson-databind -2.9.6.jar: 2.9.6] en com.fasterxml.jackson.databind.ObjectWriter.writeValue (ObjectWriter.java:913) ~ [Jackson-databind-2.9.6.jar: 2.9.6] en org.springframework .http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal (AbstractJackson2HttpMessageConverter.java:286) ~ [primavera-web-4.3.18.RELEASE.jar: 4.3.18.RELEASE] ... 58 marcos comunes omite9.6.jar: 2.9.6] en org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal (AbstractJackson2HttpMessageConverter.java:286) ~ [primavera-web-4.3.18.RELEASE.jar: 4.3.18.RELEASE]. .. 58 marcos comunes omitido9.6.jar: 2.9.6] en org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal (AbstractJackson2HttpMessageConverter.java:286) ~ [primavera-web-4.3.18.RELEASE.jar: 4.3.18.RELEASE]. .. 58 marcos comunes omitido

kvService sólo devuelve los datos de Redis. Se analiza el tipo de datos Hash ( https://redis.io/topics/data-types ) a objeto Hash se define en proto. Donde hash> categoría es clave principal de hash y los valores de hash de Redis tipo de datos se convierte en KVPair definido en proto. No puedo mostrar todo el código fuente, porque llama a otros sistemas y el código fuente es muy largo.

kvService vuelve objeto hash válido, pero a excepción ocurre cuando regrese este objeto Hash y trata de primavera convertirlo a JSON.

dependencias importantes en mi build.gradle:

def versions = [
        logback: '1.2.3',
        owner: '1.0.10',
        jackson: '2.9.6',

        guava: '25.1-jre',
        guice: '4.2.0',
        grpc: '1.9.1',
        protoc: '3.5.1',

        redis: '2.9.0',
]

{dependencias

compile group: 'ch.qos.logback', name: 'logback-classic', version: versions.logback
compile group: 'org.aeonbits.owner', name: 'owner', version: versions.owner

compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: versions.jackson
compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: versions.jackson
compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: versions.jackson

compile group: 'com.google.guava', name: 'guava', version: versions.guava
compile group: 'com.google.inject', name: 'guice', version: versions.guice
compile group: 'io.grpc', name: 'grpc-netty', version: versions.grpc
compile group: 'io.grpc', name: 'grpc-protobuf', version: versions.grpc
compile group: 'io.grpc', name: 'grpc-stub', version: versions.grpc
compile 'org.glassfish:javax.annotation:10.0-b28'


compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.2.1'
compile group: 'javax.activation', name: 'activation', version: '1.1.1'

compile group: 'redis.clients', name: 'jedis', version: versions.redis

}

Como se puede ver en mi definición protobuf NO ES cualquier referencia a sí misma.

¿Hay alguna forma posible para solucionar este problema?

VLP:

Clase UnknownFieldSet(llegar a través de método generado Hash.getUnknownFields()) contiene getter getDefaultInstanceForType()que devuelve singleton instancia de UnknownFieldSet. Este singleton propia instancia referencias en getDefaultInstanceForType()y Jackson-databind no puede manejar esto automáticamente (ver Edit2 abajo).

Es posible que desee utilizar JsonFormat de com.google.protobuf:protobuf-java-utilque utiliza codificación canónica en lugar de Jackson.

¡Buena suerte!

EDITAR> En primavera hay ProtobufJsonFormatHttpMessageConverter

Edit2> Por supuesto que podría manejar esta situación mediante mezcla en Anotaciones , pero en mi humilde opinión JsonFormat es definitivamente el camino a seguir ...

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=190858&siteId=1
Recomendado
Clasificación