假设我在.proto文件中有一条消息,其中包含以下内容
Message Foo {
Message Bar {
optional int32 a = 1;
optional int32 b = 2;
}
optional Bar bar = 1;
}
在Java中,无论如何设置字段a只使用字符串“bar.a”?理想情况下,我想编写如下方法:
public Foo.Builder apply(Foo.Builder builder, String fieldPath, Object value) {
// fieldPath == "bar.a"
// This doesn't work
FieldDescriptor fd = builder.getDefaultInstanceForType().findFieldByName(fieldPath);
builder = builder.setField(fd, value);
}
但是当我这样做时,我得到一个IllegalArgumentException。
有谁知道如何以通用的方式做到这一点?
我也需要走另一条路
public Object getValue(Foo message, String fieldPath) {
// This doesn't work
FieldDescriptor fd = message.getDefaultInstanceForType().findFieldByName(fieldPath);
return message.getField(fieldPath);
}
作为一个注释,如果fieldPath不包含分隔符(“。”)并引用基本消息,而不是嵌套消息,则此方法可以正常工作。
答案 0 :(得分:6)
您需要将字段路径拆分为“。”并进行一系列查找,例如
Message subMessage =
(Message)message.getField(
message.getDescriptorForType().findFieldByName("bar"));
return subMessage.getField(
subMessage.getDescriptorForType().findFieldByName("a"));
或者写:
FieldDescriptor desc = message.getDescriptorForType().findFieldByName("bar");
Message.Builder subBuilder = (Message.Builder)builder.getFieldBuilder(desc);
subBuilder.setField(
subMessage.getDescriptorForType().findFieldByName("a"), value);
builder.setField(desc, subBuilder.build());
你当然可以编写一个分割字符串的库,并在一次调用中完成所有查找(并进行适当的错误检查)。