代码之家  ›  专栏  ›  技术社区  ›  Harry

如何屏蔽Protobuf中的某些字段

  •  3
  • Harry  · 技术社区  · 8 年前

    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"
    

    有办法做我想做的吗

    2 回复  |  直到 8 年前
        1
  •  3
  •   Chris Nauroth    8 年前
    FieldMaskUtil.merge(FieldMaskUtil.fromString("name"), request, modifieldRequest);
    

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

    不,根据JavaDocs FieldMask ,行为与您描述的相反:

    字段掩码用于指定应

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

    注意这些解决方案在模式演化方面的差异。选择哪一个最合适取决于您的需求。

        2
  •  1
  •   Eddie Mayfield    8 年前

    如果您真的想删除名称字段,可以这样做:

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

    这应该会产生你想要的结果。