如何屏蔽 Protobuf 中的某些字段

2024-05-12

我找不到一种方法来屏蔽 protobuf 结构中的某些字段。我确实阅读了有关 FieldMaskUtil 的内容并尝试了几个示例,但它似乎做了相反的操作,即复制 FieldMask 中提到的字段,这与我想要的不同。这是示例结构和相应的测试代码。

Proto:

syntax = "proto3";

package model;

option java_package = "test.demo.services.protobuf.customer.model";
option java_outer_classname = "CustomerProto";

message Accounts {
  repeated Account account = 1;
}

message Account {

  int32 id = 1;
  string number = 2;
  int32 customer_id = 3;

}

 message Customers {
   repeated Customer customers = 1;
}

message Customer {

  int32 id = 1;
  string pesel = 2;
  string name = 3;
  CustomerType type = 4;
  repeated Account accounts = 5;

  enum CustomerType {
    INDIVIDUAL = 0;
    COMPANY = 1;
  }

}

这是示例测试代码

package test.demo.services.protobuf.customer.model;

import org.junit.Test;
import test.demo.services.protobuf.customer.model.CustomerProto.Customer;
import com.google.protobuf.util.FieldMaskUtil;


public class TestMerge {


  @Test
  public void eraseFields() {

        Customer request = Customer.newBuilder().setId(10).setPesel("12345").setName("Harry Alto").build();
    // Erase name
      Customer.Builder modifieldRequest = Customer.newBuilder();
      FieldMaskUtil.merge(FieldMaskUtil.fromString("name"), request, modifieldRequest);
      System.out.println( modifieldRequest.build().toString());
}

}

这是输出:

name: "Harry Alto"

我所期望的是打印除姓名以外的所有内容

id: 10
pesel: "12345"

有没有办法做我想做的事


FieldMaskUtil.merge(FieldMaskUtil.fromString("name"), request, modifieldRequest);

我所期望的是打印除姓名以外的所有内容

不,根据 JavaDocsFieldMask https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/FieldMask,行为与您所描述的相反:

字段掩码用于指定应该是的字段子集 由获取操作返回或由更新操作修改。

掩码充当集合交集运算,仅选择指定的字段。在您的情况下,掩码仅指定“名称”,因此这就是它选择的内容。

您正在寻找的行为实际上是一个集合补码操作,选择所有未指定的字段。我不知道 Protobuf API 中有内置方法可以执行此操作。自行实现此操作的选项有:

  • 构造多个FieldMask使用单独调用的实例FieldMask#fromString对于您想要保留的每个命名字段。然后,使用FieldMaskUtil#union https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/util/FieldMaskUtil#union-com.google.protobuf.FieldMask-com.google.protobuf.FieldMask-com.google.protobuf.FieldMask...-将它们全部结合起来。这将仅保留特别列出的字段。如果您稍后改进架构以添加更多字段,那么它不会选择这些新字段。您必须更改代码并将新的命名字段添加到该联合中。
  • Call MessageOrBuilder#getAllFields https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/MessageOrBuilder#getAllFields--获取消息中所有字段的描述符。迭代所有这些,使用FieldMaskUtil#union如上所述,但跳过您想要忽略的特定字段,例如“名称”。如果您稍后改进架构以添加更多字段,那么这将选取这些新字段。您无需更改代码即可开始包含这些新字段。

请注意这些解决方案中模式演变的差异。选择哪一种最合适取决于您的要求。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何屏蔽 Protobuf 中的某些字段 的相关文章

随机推荐

  • 使用 OAuth 的 Vkontakte API 不适用于验证码

    Vkontakte API 拒绝使用验证码的请求 这就是我所做的例子 在第三个请求之后我得到 验证码错误 14 需要验证码 根据添加就足够了captcha sid and captcha key参数到原始请求并重复请求 但回应依然是Capt
  • PowerShell 和 StringBuilder

    我是 PowerShell 新手 但熟悉 NET 类 我在用System Text StringBuilder在 PowerShell 脚本中 脚本是这样的 Function MyStringFunc String line r New O
  • 英镑符号在商店中显示为未知字符

    对于商店中每次出现的英镑符号 我都会看到一个 黑色菱形中的问号符号 谷歌搜索得到了字符集的建议 我的设置为 utf 8 如下 我相信这家商店最初是在 Os commerce 中开设的 在货币表中 我使用了 pound 的 ascii 代码
  • 安全转义表名/列名

    我在 php 中使用 PDO 因此无法使用准备好的语句转义表名或列名 以下是我自己实现它的万无一失的方法 tn str replace REQUEST tn column str replace REQUEST column sql SEL
  • 查询参数和assert_generates/assert_routing - 我缺少什么?

    我想我已经介绍了使用查询参数测试路由的排列 但没有一种方法通过 在我的 paths rb 中 我有以下内容 resources items 然后对于我的功能测试我有 require ruby debug require test helpe
  • FFmpeg 不适用于 android 10,直接进入 onFailure(String message) 并显示空消息

    我在我的一个项目中使用 FFmpeg 进行视频压缩 在 Android 10 Google Pixel 3a 上 对于发送执行的任何命令 它会直接进入 onFailure String message 并显示空消息 所以我在我的应用程序 g
  • Unity3d 中的多线程脚本调用

    我试图在Unity3d中实现多线程脚本执行 但是Unity库似乎没有提供方法 我们必须使用Mono提供的System Threading 但他们提到 Unity Scripting 不是线程安全的 我可以使用 System threadin
  • 在选择器视图中为行实现的标题没有改变字体?

    我尝试更改选择器视图中标题的字体 但由于某种原因我不能 我可以更改标题的颜色 但字体保持不变 func pickerView pickerView UIPickerView attributedTitleForRow row Int for
  • 如何将 {% capture %} 变量从视图传递到 Jekyll/Liquid 中的布局?

    我正在尝试在 Jekyll 中重建一个博客 我偶然发现了一个简单的任务 假设我有以下一组模板 默认 html head content frontpage html layout default capture head Frontpage
  • 为什么一个线程会中断另一个线程[重复]

    这个问题在这里已经有答案了 在Java多线程应用程序中 我们处理InterruptedThreadException 如果另一个线程中断当前线程 则会抛出此异常 现在 当另一个线程知道它将导致异常时 它可能想要中断当前线程的原因是什么 很多
  • 是否可以使用显式实现的接口属性对类进行 json 序列化?

    interface A string Name get set interface B string Name get set class C A B string A Name get set string B Name get set
  • MySQL INSERT 无需指定每个非默认字段(#1067 - “表”的默认值无效)

    我已经见过好几次了 我有一台服务器允许我插入一些值 而无需指定其他值 如下所示 INSERT INTO table SET value a a value b b value c 是一个没有设置默认值的字段 但在这里工作正常 当脚本移动到新
  • 使用 pdfkit 和 FastAPI 下载 PDF 文件

    我将使用 FastAPI 创建一个 API 将HTML页面到 PDF 文件 使用pdfkit 但是 它将文件保存到我的本地磁盘 当我在线提供此API后 用户如何将该PDF文件下载到他们的计算机上 from typing import Opt
  • 从 Excel 获取输入并在 python 脚本中使用这些输入

    如何从 excel 获取输入并在 python 中使用这些输入 看一眼xlrd http pypi python org pypi xlrd 这是我发现的学习如何使用它的最佳参考 http www dev explorer com arti
  • 将 NSData 视频文件合并为一个视频文件

    我有一堆视频文件想要合并成一个视频文件 我正在使用 NSMutableData 来完成该任务 NSMutableData concatenatedData NSMutableData alloc init for int i 0 i lt
  • BigDecimal 的 JPA @Size 注释

    我该如何使用 SizeMySQL 的注释DECIMAL x y 列 我在用着BigDecimal 但是当我尝试包括 Size max它不起作用 这是我的代码 Size max 7 2 Column name weight private B
  • 从命令行获取 NuGet.exe 版本

    我想得到NuGet exe使用命令行的版本 我知道我可以按照说明获取作为 Visual Studio 一部分运行的 NuGet 版本here http docs nuget org docs start here nuget faq How
  • DynamoDB 中的时间戳应使用什么数据类型?

    我是 DynamoDB 新手 我希望创建一个使用 DeviceID 作为哈希键 时间戳作为范围键和一些数据的表 DeviceID 123 Timestamp 2016 11 11T17 21 07 5272333Z X 12 Y 35 在
  • STM32F4 板上的 SPI 从机设置

    我正在尝试通过主从配置中的 SPI 在两个 STM32F4 发现板之间进行通信 我已经有了主设备的代码 但我对需要对从设备的 SPI 初始化进行的更改感到有点困惑 我还想在主机发送数据时实现中断 而不是让从机一直轮询 RXNE 寄存器 但是
  • 如何屏蔽 Protobuf 中的某些字段

    我找不到一种方法来屏蔽 protobuf 结构中的某些字段 我确实阅读了有关 FieldMaskUtil 的内容并尝试了几个示例 但它似乎做了相反的操作 即复制 FieldMask 中提到的字段 这与我想要的不同 这是示例结构和相应的测试代