Protobuf map type JSON format uses string literal “key” and “value” not the actual values
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I am trying to convert a protobuf object to JSON format using com.googlecode.protobuf.format.JsonFormat
but the map
type came out unexpected.
My message is like this
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;
}
The issue is the JSON format of the Response
object I created
Response response = ...
Return new ResponseEntity<>(new JsonFormat().printToString(response), HttpStatus.OK);
I expect the errors be formatted as a map keyed by the string value (of the map key)
...
"errors": {
"someID" : {
"message": "blah blah",
"type": "ERROR"
}
}
However the actual output is (I evaluated only the new JsonFormat().printToString(response)
part in intellij)
...
"errors": {
"key": "someID",
"value": {
"message": "blah blah",
"type": "ERROR"
}
}
I hope it's some small configuration I missed to make protobuf (or Jackson?) to be aware of the actual key value ? not using "key" and "value".
BTW, what's the point of having literal "key" and "value" field in a map
type ? You can't do constituent lookup with it and you might just use a custom type/object.
java json serialization protocol-buffers protobuf-java
add a comment |
I am trying to convert a protobuf object to JSON format using com.googlecode.protobuf.format.JsonFormat
but the map
type came out unexpected.
My message is like this
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;
}
The issue is the JSON format of the Response
object I created
Response response = ...
Return new ResponseEntity<>(new JsonFormat().printToString(response), HttpStatus.OK);
I expect the errors be formatted as a map keyed by the string value (of the map key)
...
"errors": {
"someID" : {
"message": "blah blah",
"type": "ERROR"
}
}
However the actual output is (I evaluated only the new JsonFormat().printToString(response)
part in intellij)
...
"errors": {
"key": "someID",
"value": {
"message": "blah blah",
"type": "ERROR"
}
}
I hope it's some small configuration I missed to make protobuf (or Jackson?) to be aware of the actual key value ? not using "key" and "value".
BTW, what's the point of having literal "key" and "value" field in a map
type ? You can't do constituent lookup with it and you might just use a custom type/object.
java json serialization protocol-buffers protobuf-java
add a comment |
I am trying to convert a protobuf object to JSON format using com.googlecode.protobuf.format.JsonFormat
but the map
type came out unexpected.
My message is like this
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;
}
The issue is the JSON format of the Response
object I created
Response response = ...
Return new ResponseEntity<>(new JsonFormat().printToString(response), HttpStatus.OK);
I expect the errors be formatted as a map keyed by the string value (of the map key)
...
"errors": {
"someID" : {
"message": "blah blah",
"type": "ERROR"
}
}
However the actual output is (I evaluated only the new JsonFormat().printToString(response)
part in intellij)
...
"errors": {
"key": "someID",
"value": {
"message": "blah blah",
"type": "ERROR"
}
}
I hope it's some small configuration I missed to make protobuf (or Jackson?) to be aware of the actual key value ? not using "key" and "value".
BTW, what's the point of having literal "key" and "value" field in a map
type ? You can't do constituent lookup with it and you might just use a custom type/object.
java json serialization protocol-buffers protobuf-java
I am trying to convert a protobuf object to JSON format using com.googlecode.protobuf.format.JsonFormat
but the map
type came out unexpected.
My message is like this
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;
}
The issue is the JSON format of the Response
object I created
Response response = ...
Return new ResponseEntity<>(new JsonFormat().printToString(response), HttpStatus.OK);
I expect the errors be formatted as a map keyed by the string value (of the map key)
...
"errors": {
"someID" : {
"message": "blah blah",
"type": "ERROR"
}
}
However the actual output is (I evaluated only the new JsonFormat().printToString(response)
part in intellij)
...
"errors": {
"key": "someID",
"value": {
"message": "blah blah",
"type": "ERROR"
}
}
I hope it's some small configuration I missed to make protobuf (or Jackson?) to be aware of the actual key value ? not using "key" and "value".
BTW, what's the point of having literal "key" and "value" field in a map
type ? You can't do constituent lookup with it and you might just use a custom type/object.
java json serialization protocol-buffers protobuf-java
java json serialization protocol-buffers protobuf-java
asked Nov 16 '18 at 11:45
CrazyGreenHandCrazyGreenHand
1161415
1161415
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
This code works perfectly for me:
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));
}
}
The output is:
{
"candidates": [{
}, {
}, {
}],
"errors": {
"error1": {
"message": "error1",
"type": "ERROR"
},
"error2": {
"message": "error2",
"type": "WARNING"
}
}
}
Which has no key
s and value
as you see. Make sure that you printed not the message itself, but the result of JsonFormat.printer().print()
. Basically, key
and value
s you've seen are from internal toString()
implementation of Protobuf Message
.
And the full class name for JsonFormat
is com.google.protobuf.util.JsonFormat
, not com.googlecode.protobuf.format.JsonFormat
.
Thank you for your help ! Indeed I usedcom.googlecode.protobuf.format.JsonFormat
instead ofcom.google.protobuf.util.JsonFormat
which was the issue. The googlecode one seems to be an out of date formatting util ?
– CrazyGreenHand
Nov 16 '18 at 16:50
I guess, yes, it's outdated. All Google results refer tocom.google.protobuf.util.JsonFormat
.
– madhead
Nov 16 '18 at 17:17
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53337220%2fprotobuf-map-type-json-format-uses-string-literal-key-and-value-not-the-actu%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
This code works perfectly for me:
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));
}
}
The output is:
{
"candidates": [{
}, {
}, {
}],
"errors": {
"error1": {
"message": "error1",
"type": "ERROR"
},
"error2": {
"message": "error2",
"type": "WARNING"
}
}
}
Which has no key
s and value
as you see. Make sure that you printed not the message itself, but the result of JsonFormat.printer().print()
. Basically, key
and value
s you've seen are from internal toString()
implementation of Protobuf Message
.
And the full class name for JsonFormat
is com.google.protobuf.util.JsonFormat
, not com.googlecode.protobuf.format.JsonFormat
.
Thank you for your help ! Indeed I usedcom.googlecode.protobuf.format.JsonFormat
instead ofcom.google.protobuf.util.JsonFormat
which was the issue. The googlecode one seems to be an out of date formatting util ?
– CrazyGreenHand
Nov 16 '18 at 16:50
I guess, yes, it's outdated. All Google results refer tocom.google.protobuf.util.JsonFormat
.
– madhead
Nov 16 '18 at 17:17
add a comment |
This code works perfectly for me:
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));
}
}
The output is:
{
"candidates": [{
}, {
}, {
}],
"errors": {
"error1": {
"message": "error1",
"type": "ERROR"
},
"error2": {
"message": "error2",
"type": "WARNING"
}
}
}
Which has no key
s and value
as you see. Make sure that you printed not the message itself, but the result of JsonFormat.printer().print()
. Basically, key
and value
s you've seen are from internal toString()
implementation of Protobuf Message
.
And the full class name for JsonFormat
is com.google.protobuf.util.JsonFormat
, not com.googlecode.protobuf.format.JsonFormat
.
Thank you for your help ! Indeed I usedcom.googlecode.protobuf.format.JsonFormat
instead ofcom.google.protobuf.util.JsonFormat
which was the issue. The googlecode one seems to be an out of date formatting util ?
– CrazyGreenHand
Nov 16 '18 at 16:50
I guess, yes, it's outdated. All Google results refer tocom.google.protobuf.util.JsonFormat
.
– madhead
Nov 16 '18 at 17:17
add a comment |
This code works perfectly for me:
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));
}
}
The output is:
{
"candidates": [{
}, {
}, {
}],
"errors": {
"error1": {
"message": "error1",
"type": "ERROR"
},
"error2": {
"message": "error2",
"type": "WARNING"
}
}
}
Which has no key
s and value
as you see. Make sure that you printed not the message itself, but the result of JsonFormat.printer().print()
. Basically, key
and value
s you've seen are from internal toString()
implementation of Protobuf Message
.
And the full class name for JsonFormat
is com.google.protobuf.util.JsonFormat
, not com.googlecode.protobuf.format.JsonFormat
.
This code works perfectly for me:
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));
}
}
The output is:
{
"candidates": [{
}, {
}, {
}],
"errors": {
"error1": {
"message": "error1",
"type": "ERROR"
},
"error2": {
"message": "error2",
"type": "WARNING"
}
}
}
Which has no key
s and value
as you see. Make sure that you printed not the message itself, but the result of JsonFormat.printer().print()
. Basically, key
and value
s you've seen are from internal toString()
implementation of Protobuf Message
.
And the full class name for JsonFormat
is com.google.protobuf.util.JsonFormat
, not com.googlecode.protobuf.format.JsonFormat
.
answered Nov 16 '18 at 12:20
madheadmadhead
14.9k1389126
14.9k1389126
Thank you for your help ! Indeed I usedcom.googlecode.protobuf.format.JsonFormat
instead ofcom.google.protobuf.util.JsonFormat
which was the issue. The googlecode one seems to be an out of date formatting util ?
– CrazyGreenHand
Nov 16 '18 at 16:50
I guess, yes, it's outdated. All Google results refer tocom.google.protobuf.util.JsonFormat
.
– madhead
Nov 16 '18 at 17:17
add a comment |
Thank you for your help ! Indeed I usedcom.googlecode.protobuf.format.JsonFormat
instead ofcom.google.protobuf.util.JsonFormat
which was the issue. The googlecode one seems to be an out of date formatting util ?
– CrazyGreenHand
Nov 16 '18 at 16:50
I guess, yes, it's outdated. All Google results refer tocom.google.protobuf.util.JsonFormat
.
– madhead
Nov 16 '18 at 17:17
Thank you for your help ! Indeed I used
com.googlecode.protobuf.format.JsonFormat
instead of com.google.protobuf.util.JsonFormat
which was the issue. The googlecode one seems to be an out of date formatting util ?– CrazyGreenHand
Nov 16 '18 at 16:50
Thank you for your help ! Indeed I used
com.googlecode.protobuf.format.JsonFormat
instead of com.google.protobuf.util.JsonFormat
which was the issue. The googlecode one seems to be an out of date formatting util ?– CrazyGreenHand
Nov 16 '18 at 16:50
I guess, yes, it's outdated. All Google results refer to
com.google.protobuf.util.JsonFormat
.– madhead
Nov 16 '18 at 17:17
I guess, yes, it's outdated. All Google results refer to
com.google.protobuf.util.JsonFormat
.– madhead
Nov 16 '18 at 17:17
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53337220%2fprotobuf-map-type-json-format-uses-string-literal-key-and-value-not-the-actu%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown