2013-07-08 3 views
2

Я попытался сериализации и deseriliaze данные LinkedHashMap следующим образом:Flex JSON не в состоянии правильно сериализации/десериализации LinkedHashMap

LinkedHashMap<String, Object> o = new LinkedHashMap<String, Object>(); 
o.put("1", "a"); 
o.put("2", "b"); 
o.put("3", "c"); 
o.put("4", new BigDecimal("9999999999999999999999.00999999999999999999999")); 

String serialize = new JSONSerializer().deepSerialize(o); 
System.out.println("serialize" + serialize); 

LinkedHashMap deserialize = new JSONDeserializer<LinkedHashMap>().deserialize(serialize, LinkedHashMap.class); 
System.out.println("deserialize:" + deserialize); 

и я получаю ClassCastException:

serialize{"1":"a","2":"b","3":"c","4":9999999999999999999999.00999999999999999999999} 
Exception in thread "main" java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.LinkedHashMap 
    at com.JSONUtil.main(JSONUtil.java:161) 

Так что я попытался немного другой подход, когда десериализации следующим образом:

HashMap deserialize = new JSONDeserializer<HashMap>().deserialize(serialize, HashMap.class); 
System.out.println("deserialize:" + deserialize); 

На этот раз я получаю результат, но Карта неупорядочена (Я думаю, потому что теперь он использует HashMap). Кроме того, значение BigDecimal не отображается, как исходный формат.

deserialize:{3=c, 2=b, 1=a, 4=1.0E22} 

Похоже, что у FlexJSON есть проблема с отсортированной Картой. Я предполагаю, что это связано с тем, что он не имеет возможности поместить запись «class», как в примере ниже, например.

"class":"ch.qos.logback.classic.Logger","debugEnabled":true,"errorEnabled":true,"infoEnabled":true} 

или, возможно, есть другой способ сделать это. Кто-нибудь может помочь? Спасибо


После введения ObjectFactory как предложено chubbsondubs:

объект
LinkedHashMap deserialize = new JSONDeserializer<LinkedHashMap>() 
.use(LinkedHashMap.class, new ObjectFactory() { 
public Object instantiate(ObjectBinder context, Object value, Type targetType, Class targetClass) { 
    System.out.println("mymap:"value); 
} 
}).deserialize(serialize, LinkedHashMap.class); 

значение имеет тип HashMap и печатает:

mymap:{3=c, 2=b, 1=a, [email protected]} 

ответ

2

По умолчанию объект без ввода информации интерпретируется как HashMap, который объясняется в документах. Время, в течение которого он не будет использовать HashMap, может определить тип объекта либо из встроенного свойства класса (который работает, но небезопасен по сети), указанного типа по пути объекта, либо если вы десериализируетесь в типизированный объект, из которого он может интерпретировать тип.

Таким образом, классы, подобные стандартным коллекциям, не позволяют Flexjson вывести содержащийся тип из класса Collection/Map, потому что это простые ссылки на объекты во время выполнения. Номера - это еще одна область, где JSON не указывает информацию о типе. Когда мы сопоставляем число с Java, которое может быть одним из нескольких вариантов: байт, короткий, int, long, BigInteger, float, double, BigDecimal. Flexjson должен сделать вызов, если не указана информация для ввода. По умолчанию он использует double, если его десятичное и длинное, если оно целое. В вашем случае это двойной, и именно поэтому он показывает его в экспоненциальном формате.

Вам необходимо указать типы, которые вы хотите. Используя либо типизированный объект, настраивая тип на пути объекта, либо создавая собственный объект ObjectFactory. Я думаю, что ObjectFactory - единственный вариант для вас, если вы не можете создать типизированный объект. Причина состоит в том, что значения в вашей карте различаются по типу. Некоторые записи являются строками, где другой - BigDecimal. Таким образом, вам понадобится специальный объект ObjectFactory, который знает, как создать экземпляр LinkedHashMap и скопировать все ключи из источника в целевую, преобразуя их в BigDecimal, если значение источника - JsonNumber.

+0

Спасибо, но в то время сортировка карты уже изменилась. Смотрите мой отредактированный комментарий наверху. –

+0

Это потому, что вы фактически ничего не делали в своей ObjectFactory. То, что вы выписали, это HashMap (который не имеет порядка), который использует flexjson, прежде чем он свяжет этот HashMap с объектом, созданным ObjectFactory. Вы должны перевести это в LinkedHashMap, создав экземпляр внутри ObjectFactory и перемещая в него значения. – chubbsondubs

Смежные вопросы