New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: add an optional fallback type parameter for the toplevel json container to JsonReader.jsonToJava(json); #15
Comments
Successfully, I have found a solution - I write it as comment if somebody has the same problem and you don't want to add this feature: JsonObject jsonObject = (JsonObject) JsonReader.jsonToMaps(jsonString);
if(jsonObject.getType() == null) jsonObject.setType("package.FallbackClassName");
Object finalJavaObject = new JsonReader().jsonObjectsToJava(jsonObject); Thanks again for this nice piece of work! |
...as far as I found a solution for reading those json-Strings without toplevel type, it is a bit hard to create those with json-io. I did so with Collections and Arrays, by subclassing JsonWriter, adding a method write(Object obj, boolean showTopLevelType). This method simply adds the possibility to specify the 'showType' parameter in the writeImpl invocation - everything else is identical to the origin write(Object obj) method.
Thanks a lot |
@type is not mandetory to be specified in the JSON. There are many circumstances where you can leave it out: In the case of any field of an object, the @type parameter can be left off, if the value associated to the field is the exact same type of the field (usually the case). When the JSON reader encounters JSON data without the @type, it looks at the field of the object, and instantiates the object as the field type in that case. Where this does not work, is when the field is an abstract class or interface. There is special handling for the Collection classes (intelligent Collection and Map types are used). @type is also required when the field type is a superclass of the actual type written. For example, if you a class Person and Employee is derived from Person. If the field type is Person but it is polymorphically pointing to an Employee, and the @type is not written, then the JsonReader cannot instantiate the class as an Employee, as it does not know that what to instantiate. The best it could do is instantiate a Person. If person is concrete, then it will instantiate it as Person, and the Employee fields would be dropped (not desired). JsonWriter allows compares the instance type to the field type and does NOT write the @type out in these cases, so that the resulting JSON is smaller. Another case where @type can be dropped is when you have a specific array type. An Employee[] of Employee objects. In this case, the @type, if missing on the Employee objects inside the array, will be inferred from the type of the Array. However, if the array was an Object[], then it cannot make this inference. JsonWriter compares the Objects inside an array [] when writing them, and drops the @type in this case to make the resulting JSON smaller. @type can be left off of Object[] of Strings, Object[] of longs, Object[] of booleans, Object[] of doubles. In all those cases, it can infer the type. Furthermore, these can be placed into the JSON as their native types, as opposed to JSON Objects{} in this case. JsonWriter special handles these types so that they are written as JSON primitives (long, double, String, boolean). |
I can make requested APIs protected to allow for subclassing. In the next release of json-io I may change that. I want to stew on this a little bit. For now, use Reflection like you did, as those APIs are not likely changing and your code will be fine. |
Thanks for clarification jdereg! |
The optionalArg TYPE parameter was just added in json-io 4.0.1 which allows the @type to be completely turned off. This will create JSON that can be sent to Javascript, however, the created JSON may often not be properly reconstructed as a Java graph. The option does add utility, for instance, sending JSON to a non-Java destination. |
We give the possibility to specify http get parameters also as json strings, to allow class objects as parameter types for the web interfaces also.
The problem is, by using json-io, specifying @type in the json string is mandatory for deserialization, right? Thus, the users have to specify it, which is not so nice (for the return values its fine of course, but for parameters?)
I love the way json-io deals with types, for me, it is the best solution to support polymorphism I have seen in such a library. Nevertheless, in this case, the underlying type of the parameter normally not changes - it should be transparent for the (e.g. javascript) user of the interface who creates the json, and clear for the server.
Is it possible to add another method to JsonReader.jsonToJava(String json, Class toplevelFallbackType) - where toplevelFallbackType could be also String, Type, etc. of course.
This parameter would then be used as fallback if the @type was not specified in the toplevel json object.
I know this would not work with polymorphism, but it would help us a lot and would be maybe a nice enhanchement of json-ios functionality:)
Thanks and best regards
Christian
The text was updated successfully, but these errors were encountered: