Java:字符串中的protobuf

时间:2018-09-03 14:02:34

标签: java protocol-buffers

我正在使用带有grpc的proto3,并且正在寻找一种更有效的方式来创建protobuf消息,而无需使用构建器并将其填充。

如果我有一个字符串(来自Message.toString()),我可以用该字符串重新创建消息吗?

如果我有消息类型

Right click your project > 'Run configuration' 

以及以下输出:

message TestMessage {
    bool status = 1;
    uint64 created = 2;
    TestNested submessage = 3;


    message TestNested {
        int32 messageNumber = 1;
        Entry entry = 2;
    }

    message Entry {
        int32 id = 1;
        EntryType entryType = 2;
    }

    enum EntryType {
        DEFAULT_ENTRY = 0;
        OTHER_ENTRY = 1;
    }
}

如何创建TestMessage?我查看了JavaDoc,看是否有一个status: true created: 1534240073415 submessage { messageNumber: 3 entry{ id: 47957 entryType: DEFAULT_ENTRY } } 方法接受一个字符串,但是我没有赢。

2 个答案:

答案 0 :(得分:1)

我正在寻找 TextFormat 解析器。 Message.toString()打印的格式是TextFormat表示形式。

要转换回protobuf消息,我做了以下工作:

TestMessage testMessage = new TestMessage.newBuilder();

CharSequence myText = "status: true\n ...";

com.google.protobuf.TextFormat.getParser().merge(myText, testMessage);

答案 1 :(得分:0)

下面的代码段/客户代码,用于“普通测试格式”到原型值之间的各种情况转换。大多数事情在protobuf documentation中都是显而易见的。

原始文件:phonemetadatabrokerproto.proto

message CastAroundCriteria {
  optional string region_code = 1;
  optional int32 prefix = 2;
}
  public static void main(String args[]) {

    // Creating a value object in program through proto APIs.
    Phonemetadatabrokerproto.CastAroundCriteria cacb = Phonemetadatabrokerproto.CastAroundCriteria.newBuilder().setRegionCode("AE").setPrefix(20).build();
    System.out.println(cacb);

    // To travel over the wire as Byte string. Not in plain text, so not using special TextFormat kind of APIs. You have many other alternatives, please serach.
    Phonemetadatabrokerproto.CastAroundCriteria cacb2 = null;
    try{
    cacb2 = Phonemetadatabrokerproto.CastAroundCriteria.parseFrom(cacb.toByteString());
      } catch (InvalidProtocolBufferException e) {
      e.printStackTrace();
    }
    System.out.println(cacb2);

    // When vanilla string literals has to be passed between the APIs / on wire. Using TextFormat APIs
    CharSequence inputCS = cacb.toString();
    Phonemetadatabrokerproto.CastAroundCriteria.Builder cacb3 = null;
        try{
    cacb3 = Phonemetadatabrokerproto.CastAroundCriteria.newBuilder();
    TextFormat.getParser().merge(inputCS, cacb3);
        } catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println(cacb3);

    // Hardcoded string unmarshalling to proto.
    CharSequence rawInput = "region_code: \"AE\" prefix: 20";
    Phonemetadatabrokerproto.CastAroundCriteria.Builder cacb4 = null;
        try{
    cacb4 = Phonemetadatabrokerproto.CastAroundCriteria.newBuilder();
    TextFormat.getParser().merge(rawInput, cacb4);
        } catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println(cacb4);

    // Dynamic commandline input has to be string literal "region_code: 'AE' prefix: 20" when running in linux. Otherwise we need to escape \" in
    // command input. More of bash is culprit. :)
    CharSequence cmdInput = args[0];
    Phonemetadatabrokerproto.CastAroundCriteria.Builder cacb5 = null;
        try{
    cacb5 = Phonemetadatabrokerproto.CastAroundCriteria.newBuilder();
    TextFormat.getParser().merge(cmdInput, cacb5);
        } catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println(cacb5);
  }

请忽略某些命名约定,例如类名称为Phonemetadatabrokerproto以及异常处理。