Sending protobuf as JSON in spring-boot
我正在使用带有此具体定义的protobufs。
1 2 3 4 5 6 7 8 9 | message Hash { string category = 1; repeated KVPair content = 2; } message KVPair { string key = 1; string value = 2; } |
我想通过spring-boot应用程序将其作为JSON发送。
我将此程序包添加到了gradle依赖项中:
1 | compile group: 'com.google.protobuf', name: 'protobuf-java', version: '3.6.1' |
当我尝试使用此代码输出哈希生成的对象时:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @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; } } |
它引发了这个最终的异常:
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct self-reference leading to cycle (through reference chain: com.blaazha.crm.proto.Hash["unknownFields"]->com.google.protobuf.UnknownFieldSet["defaultInstanceForType"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1191) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter._handleSelfReference(BeanPropertyWriter.java:944) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:721) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1396) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:913) ~[jackson-databind-2.9.6.jar:2.9.6]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:286) ~[spring-web-4.3.18.RELEASE.jar:4.3.18.RELEASE]
... 58 common frames omitted
kvService仅从redis返回数据。它将Hash数据类型(https://redis.io/topics/data-types)解析为proto中定义的Hash对象。其中Hash-> category是hash的主键,而hash redis数据类型中的值将转换为proto中定义的KVPair。我无法显示所有源代码,因为它会调用其他系统并且源代码很长。
kvService返回有效的Hash对象,但是当我返回此Hash对象并且spring尝试将其转换为JSON时发生异常。
我的build.gradle中的重要依赖项:
1 2 3 4 5 6 7 8 9 10 11 12 | 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', ] |
依赖项{
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 |
}
正如您在我的protobuf定义中所看到的,它不是任何自引用。
有没有可能解决此问题的方法?
类
您可能要使用
祝好运!
编辑>对于Spring,有ProtobufJsonFormatHttpMessageConverter
EDIT2>当然,您可以使用混入注释来处理这种情况,但是IMHO JsonFormat绝对是可行的方法...