java - 有没有一种方法可以在没有代码生成的情况下编写原型(prototype)数据?

标签 java reflection protocol-buffers

我想知道是否可以使用google protobuf提供的反射API来序列化消息而无需代码生成?

Protocol buffer 允许我们在 MessageMessage.Builder 对象上使用反射在解析过程之后。但就我而言,我想知道是否可以用字段/值填充这些对象,然后将它们写入文件。

最佳答案

编码输出流

做到这一点的一种方法是了解 message is encoded并使用 CodedOutputStream使用适当的 write*() 方法编写消息字段。

例如编写以下消息:

message MyMessage {
    int foo = 1;
    string bar = 2;
}

您将使用这段代码:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
CodedOutputStream out = CodedOutputStream.newInstance(baos);
out.writeInt32(1, 1);
out.writeString(2, "s");
out.flush();
byte[] rawProtocolBuffer = baos.toByteArray();

动态消息

另一种方法是手动创建描述符,然后使用 DynamicMessage 设置相应的字段,但这比直接使用 CodedOutputStream 更像样板。

String messageName = "MyMessage";
FileDescriptorProto fileDescriptorProto = FileDescriptorProto
        .newBuilder()
        .addMessageType(DescriptorProto.newBuilder()
                .setName(messageName)
                .addField(FieldDescriptorProto.newBuilder()
                        .setName("foo")
                        .setNumber(1)
                        .setType(FieldDescriptorProto.Type.TYPE_INT32)
                        .build())
                .addField(FieldDescriptorProto.newBuilder()
                        .setName("bar")
                        .setNumber(2)
                        .setType(FieldDescriptorProto.Type.TYPE_STRING)
                        .build())
                .build())
        .build();

Descriptor messageDescriptor = FileDescriptor
        .buildFrom(fileDescriptorProto, new FileDescriptor[0])
        .findMessageTypeByName(messageName);

DynamicMessage message = DynamicMessage
        .newBuilder(messageDescriptor)
        .setField(messageDescriptor.findFieldByNumber(1), 1)
        .setField(messageDescriptor.findFieldByName("bar"), "s")
        .build();

byte[] rawProtocolBuffer = message.toByteArray();

关于java - 有没有一种方法可以在没有代码生成的情况下编写原型(prototype)数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17292073/

相关文章:

java - 推迟检查 IllegalArgumentException 的建议是什么?

objective-c - 使用反射/内省(introspection)调用参数数量未知的选择器

docker - 用于自定义模型的 TensorFlow Serving

python - 如何在 Django 中使用带有 Protocol Buffer 的 gRPC

java - 使用端口转发运行 docker 失败

java - Akka 及其错误内核

java - 带 Debug模式的 Spring 启动但禁用了自动配置报告

java - 使用java反射实例化接口(interface)?

go - 如何通过反射将非指针值复制到指针间接值

protocol-buffers - Google Protocol Buffer 和 STL 向量、映射和提升共享指针