Question

I am deserialising a json object as below

 {
     "b":"value1",
     "a":"value2",
     "d":"value3",
     "c":"value4",
     "f":"value5",
     "e":"value6"
 }

But i am getting ClassCastException as below

 java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.LinkedHashMap

My deserialisation code is

LinkedHashMap<String, String> map = new JSONDeserializer<LinkedHashMap<String, String>>().deserialize(JSONstring);

But when i use HashMap instead of LinkedHashMap it works but output gets sorted as below (Its not original order).

 {
     a=value2, 
     b=value1, 
     c=value4, 
     d=value3, 
     e=value6, 
     f=value5
 }

I want to get the output in original order. I found this related link Flex JSON unable to properly serialize/deserialize LinkedHashMap but didn't get how to use ObjectFactory.

I would appreciate any help!

Thanks in advance!

Was it helpful?

Solution

(Disclaimer: I just downloaded flexjson and debugged through its source code, so my answer might be slightly incomplete.)

In short:

  • You generally cannot get the entries in original order using flexjson.
  • Even writing a custom ObjectFactory will not work.
  • This is most likely intended and correct.

In detail:

First, the use of generics in new JSONDeserializer<LinkedHashMap<String,String>>() only affects the compilable code, flexjson cannot use this information to actually return a LinkedHashMap<String,String> (this is because the compiler removes the generic and the implementing class has no information of this generic type at runtime).

So, looking deeper into what happens during deserialization, it seems that during parsing the input string, the data is automatically converted to the correct type (string, date, number, list, etc.). This is done using some kind of autodetection of the required data type, because JSON does not provide type information in its data, so flexjson has a build-in list to support data types. It can also use custom mappings to assign values to object properties when proper class information is given (on serialization, flexjson adds a field class to the data to store this type information; or you can manually set this, see documentation).

But the main point is that - according to http://json.org -

An object is an unordered set of name/value pairs.

flexjson internally uses an (unordered) map to store the temporary object keys and values. Even if you tell flexjson to return the data as a LinkedHashMap the data is yet put into a HashMap before it will be converted to a LinkedHashMap, so the original order is not available at that point. (This might be fixed by replacing the map creation in flexjson.JSONTokener, line 442 with a LinkedHashMap but I didn't try that myself.)

Conclusion:

It looks like this behaviour even cannot be changed by providing a custom ObjectFactory, so as far as I understand the code, you cannot retain the original field order. (May I ask why this is important for your project?)

So, if anybody finds a solution anyway, don't hesitate to correct me.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top