12

给定以下 json 响应:

{
    "id" : "123456",
    "name" : "John Doe",
    "email" : "john.doe@example.com"
}

以及以下user.proto文件:

message User {
    string id = 1;
    string name = 2;
    string email = 3;
}

我希望能够动态创建 protobuf 消息类(在运行时编译 .proto),这样如果 json 响应通过一个字段得到增强,"phone" : "+1234567890"我可以上传一个新版本的 protobuf 文件来包含string phone = 4并获取它protobuf 响应中公开的字段,无需重新启动服务。

如果我要从帽子中提取这些类,我希望能够按照以下代码编写一些东西。

import com.googlecode.protobuf.format.JsonFormat;
import com.googlecode.protobuf.Message;
import org.apache.commons.io.FileUtils;

...

public Message convertToProto(InputStream jsonInputStream){
    // get the latest user.proto file
    String userProtoFile = FileUtils.readFileToString("user.proto");

    Message userProtoMessage = com.acme.ProtobufUtils.compile(userProtoFile);
    Message.Builder builder = userProtoMessage.newBuilderForType(); 
    new JsonFormat().merge(jsonInputStream, Charset.forName("UTF-8"), builder);
    return builder.build();
}

是否有现有的 com.acme.ProtobufUtils.compile(...) 方法?或者如何实施?运行 protoc + load 类似乎有点过头了,但如果没有其他选择,我愿意使用它......

4

1 回答 1

5

您无法编译.proto文件(至少不是在 Java 中),但是您可以将其预编译.proto为描述符.desc

protoc --descriptor_set_out=user.desc user.proto

然后使用DynamicMessage's 解析器:

DynamicMessage.parseFrom(Descriptors.Descriptor type, byte[] data)

来源:谷歌组线程

于 2018-09-02T12:13:42.283 回答