jsonb-api icon indicating copy to clipboard operation
jsonb-api copied to clipboard

Clarification needed

Open aguibert opened this issue 4 years ago • 2 comments

Issue from @maald moved over from Yasson repo at: https://github.com/eclipse-ee4j/yasson/issues/407

Assume you have a class with 2 properties

public class Whatever {
    public int numberProp;
    public String stringProp;      // String
}

Serialize an instance to JSON

Whatever obj = new Whatever();
obj.numberProp = 1;
obj.stringProp = "hello";

String json = JsonbBuilder.create().toJson(obj);
System.out.println(json);

as expected you get something like this

{ 
   "numberProp" :  1,
   "stringProp" :  "hello"
}

Now, if you de-serialize the following JSON payload

{ 
   "numberProp" :  1,
   "stringProp" :  12345
}

Json-b will simply de-serialize a JSON number value (12345) to a Java String ("12345")! In that payload, "stringProp" clearly has a JSON number value/not a JSON string value.

The confusing part here is that Json-B serializes Java String to JSON string by making sure to include quotes but then de-serialize a JSON number (has no quotes) to Java String.

Is this a bug or the expected behavior?

Personally, I prefer fail-fast approach (let the client know there is an issue with the value/expected a JSON string) instead of masking this basic type mismatch.

aguibert avatar May 08 '20 18:05 aguibert

Hi @aguibert ,

Don't think JSON-B deserializes it but Yasson does. Johnzon for instance will fail until you set a deserializer/adapter (please ignore the wording which is not perfect ;)):

javax.json.bind.JsonbException: Unable to parse 12345 to class java.lang.String

rmannibucau avatar May 09 '20 07:05 rmannibucau

Yeah I have only tested it with Yasson. It's disappointing this even works

public class Model {
    public Integer i;  // maps to json number
    public String s;   // maps to json string
}

json values have flipped types (Json String, Json Number). Yasson reads a json string and deserialize it into Integer, reads a json number and deserialize it into String!

{
   "i"  : "1",
   "s"  :  1
}

My guess is that Yasson or the underlying JsonP runtime (I used Glassfish implementation) simply reads everything as String and then calls valueof static methods. It doesn't check the the actual JsonValue type (Json-P) to see if there's a type mismatch.

maald avatar May 23 '20 07:05 maald