JsonParseException when i try deserializing a JSON containing a string to a integer field (JsonIoUtil)

2,054 views
Skip to first unread message

Mihai Niculae

unread,
Nov 26, 2015, 5:43:41 AM11/26/15
to protostuff
So here's the data:
- Using protostuff maven plugin to generate "java_bean" sources with "generate_field_map", "builder_pattern", "primitive_numbers_if_optional" and "enums_by_name" options.
I realize that the last two might not be in effect since i'm using java_bean.
- Using protostuff-core, protostuff-api and protostuff-json, all versions 1.3.8, protostuff-json depends on jackson-core 2.4.4
- Of course, i'm using the plugin to generate the pojos from some .proto files.
Here's my problem:
While protobuf ser and deser work like a charm, i'm having issues deserializing json files.
Of course i had to use generate_field_map because in this project, I need to use the json keys by name, not index.
In some proto files, i have fields marked as int64 but the backend will send me the jsons with those fields as a string "0" for example.
When i try to deser using JsonIoUtil, using the schema that was generated by the maven plugin, it throws the following exception:
com.fasterxml.jackson.core.JsonParseException: Current token (VALUE_STRING) not numeric, can not use numeric value accessors [...]
Unfortunately i'm kind of a newbie and I have no idea whatsoever on how to fix this.

Here's an example:
foo.proto:
message Foo {
optional
string bar = 1;
optional int64 foo
= 2;
}

String foo = "{\"bar\":\"baz\",\"foo\":\"1\"}".getbytes();
Bar bar = new Bar;
Boolean numeric = false;
JsonIoUtil.mergeFrom(foo, bar, Bar.getSchema(), numeric);

Am i doing something wrong?
Wasn't the underlying jackson capable of casting an integer to a string?
I know for a fact that ObjectMapper knows how to, but I have no idea if there's a way to use it instead of ParserBase.
Also, using jackson directly to deserialize to the pojo is not an option, a lot of imports are happening in the .proto's i was provided with and there's more trouble that way.

Thanks.

Kostiantyn Shchepanovskyi

unread,
Nov 26, 2015, 2:13:04 PM11/26/15
to protostuff
There is no out-of-the box solution to read numbers if they are represented by string.

protostuff-json uses only part of jackson - lexer.

This method is called to read integer number: JsonInput.java#readInt32()
Internally it uses JsonParser#getIntValue()

Numeric accessor that can be called when the current token is of type JsonToken.VALUE_NUMBER_INT and it can be expressed as a value of Java int primitive type.

You can try to extend JsonInput and change implementation of readInt32() and other methods.

Mihai Niculae

unread,
Nov 27, 2015, 9:22:37 AM11/27/15
to protostuff
This might be a bit noobish but, sure, I can extend JsonInput, but ultimately I use JsonIOUtil, is there any way to force JsonIOUtil to use the extended implementation I wrote? Or do i need to extend al the chain of classes to re-route everything to it?

Reply all
Reply to author
Forward
0 new messages