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"
}
}
}
如您所见,其中没有 key
和 value
。确保您打印的不是消息本身,而是 JsonFormat.printer().print()
的结果。基本上,您看到的 key
和 value
s 来自 Protobuf Message
.
的内部 toString()
实现
JsonFormat
的完整 class 名称是 com.google.protobuf.util.JsonFormat
,而不是 com.googlecode.protobuf.format.JsonFormat
。
我正在尝试使用 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"
}
}
}
如您所见,其中没有 key
和 value
。确保您打印的不是消息本身,而是 JsonFormat.printer().print()
的结果。基本上,您看到的 key
和 value
s 来自 Protobuf Message
.
toString()
实现
JsonFormat
的完整 class 名称是 com.google.protobuf.util.JsonFormat
,而不是 com.googlecode.protobuf.format.JsonFormat
。