Protobuf 映射类型 JSON 格式使用字符串文字 "key" 和 "value" 而不是实际值

Protobuf map type JSON format uses string literal "key" and "value" not the actual values

我正在尝试使用 com.googlecode.protobuf.format.JsonFormat 将 protobuf 对象转换为 JSON 格式,但 map 类型意外出现。

我的留言是这样的

message Response {
   repeated Candidate candidates = 1;
   map<string, ErrorMessage> errors = 2;
}

message ErrorMessage {
   string message = 0;
   ErrorType type = 1;
}

enum ErrorType {
   ERROR = 0;
   WARNING = 1;
}

问题是我创建的Response对象的JSON格式

Response response = ...
Return new ResponseEntity<>(new JsonFormat().printToString(response), HttpStatus.OK);

我希望将错误格式化为由(映射键的)字符串值作为键控的映射

...
"errors": {
  "someID" : {
      "message": "blah blah",
      "type": "ERROR"
  }
}

但是 actual 输出是(我只评估了 intellij 中的 new JsonFormat().printToString(response) 部分)

...
"errors": {
  "key": "someID",
  "value": {
      "message": "blah blah",
      "type": "ERROR"
  }
}

我希望这是我遗漏的一些小配置,让 protobuf(或 Jackson?)知道实际的键值?不使用 "key" 和 "value"。

顺便说一句,在 map 类型中包含文字 "key" 和 "value" 字段有什么意义?您不能用它进行成分查找,您可能只使用自定义 type/object.

这段代码非常适合我:

test.proto

syntax = "proto2";
package by.dev.madhead;
option java_outer_classname = "SO";

message Candidate {

}

enum ErrorType {
    ERROR = 0;
    WARNING = 1;
}

message ErrorMessage {
    required string message = 1;
    required ErrorType type = 2;
}

message Response {
    repeated Candidate candidates = 1;
    map<string, ErrorMessage> errors = 2;
}

App.java

public class App {
    public static void main(String[] args) throws InvalidProtocolBufferException {
        SO.Response response = SO.Response.newBuilder()
            .addCandidates(SO.Candidate.newBuilder().build())
            .addCandidates(SO.Candidate.newBuilder().build())
            .addCandidates(SO.Candidate.newBuilder().build())
            .putErrors("error1", SO.ErrorMessage.newBuilder().setMessage("error1").setType(SO.ErrorType.ERROR).build())
            .putErrors("error2", SO.ErrorMessage.newBuilder().setMessage("error2").setType(SO.ErrorType.WARNING).build())
            .build();

        System.out.println(JsonFormat.printer().print(response));
    }
}

输出为:

{
    "candidates": [{
    }, {
    }, {
    }],
    "errors": {
        "error1": {
            "message": "error1",
            "type": "ERROR"
        },
        "error2": {
            "message": "error2",
            "type": "WARNING"
        }
    }
}

如您所见,其中没有 keyvalue。确保您打印的不是消息本身,而是 JsonFormat.printer().print() 的结果。基本上,您看到的 keyvalues 来自 Protobuf Message.

的内部 toString() 实现

JsonFormat 的完整 class 名称是 com.google.protobuf.util.JsonFormat,而不是 com.googlecode.protobuf.format.JsonFormat