【问题标题】:Serialize protobuf with default values using Gson使用 Gson 使用默认值序列化 protobuf
【发布时间】:2019-11-24 22:41:55
【问题描述】:

我正在尝试将表示为 Java 类的 protobuf 消息序列化为带有 Gson 库和 ProtoTypeAdapter 的 JSON

ProtoTypeAdapter adapter = ProtoTypeAdapter.newBuilder()
        .setFieldNameSerializationFormat(CaseFormat.LOWER_UNDERSCORE, CaseFormat.LOWER_UNDERSCORE)
        .build();
Gson gson = new GsonBuilder()
        .registerTypeAdapter(SomeAutogeneratedClass.class, adapter)
        .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
        .disableHtmlEscaping()
        .create();

suchMessage.getMyIntField()  // which is 0
String serialized = gson.toJson(suchMessage)

但它似乎没有为int字段序列化0等默认值。 如何在 JSON 中包含这些具有默认值的字段?

【问题讨论】:

    标签: java json serialization gson protocol-buffers


    【解决方案1】:

    我创建了一个小脚本,它使用反射通过将默认值更改为永远无法使用的值来解决此问题。

    public static void overrideDefaultValue(Descriptors.FieldDescriptor desc, Object newDefault) throws IllegalAccessException, NoSuchFieldException {
        Field f = Descriptors.FieldDescriptor.class.getDeclaredField("defaultValue");
        f.setAccessible(true);
        f.set(desc, newDefault);
    }
    

    假设您正在尝试序列化一个表示索引的值。那么-1 是一个不可能的值。你可以这样使用它:

    overrideDefaultValue(MyMessage.getDescriptor().findFieldByName("my_field"), -1);
    

    【讨论】:

      【解决方案2】:

      我修改this line如下:

      //        final Map<FieldDescriptor, Object> fields = src.getAllFields();  // original line
      
              // --- Include default value fields (See com.google.protobuf.util.JsonFormat) ---
              final Map<FieldDescriptor, Object> fields = new TreeMap<>(src.getAllFields());
              for (FieldDescriptor field : src.getDescriptorForType().getFields()) {
                  if (field.isOptional()) {
                      if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE
                              && !src.hasField(field)) {
                          continue;
                      }
                      Descriptors.OneofDescriptor oneof = field.getContainingOneof();
                      if (oneof != null && !src.hasField(field)) {
                          continue;
                      }
                  }
                  if (!fields.containsKey(field)) {
                      fields.put(field, src.getField(field));
                  }
              }
              // ------
      

      【讨论】:

        猜你喜欢
        • 2014-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-09
        • 2016-01-30
        相关资源
        最近更新 更多