Исключение Гсона - де-гсон сложный объект - PullRequest
1 голос
/ 17 мая 2011

У меня есть объект, который содержит

открытый класс PositionsChannelApplicationGroups {

public PositionsChannelApplicationGroups(){}

    private Map<MyObj1, List<Character>> portfoliosToApplicationIds = new HashMap<MyObj1, List<Character>>();
    private Map<MyObj1, List<Character>> accountsToApplicationIds = new HashMap<MyObj2, List<Character>>();

    private Map<Character, List<MyObj1>> applicationIdToPortfolios = new HashMap<Character, List<MyObj1>>();
    private Map<Character, List<MyObj2>> applicationIdToAccounts = new HashMap<Character, List<MyObj2>>();
 }

Теперь я пытаюсь найти его на сервере и удалить его на клиенте.
Для простоты я получаю исключение, когда делаю это в одну строку

 Gson gson = new Gson();
 gson.fromJson(gson.toJson(object), PositionsChannelApplicationGroups.class);

или даже

 gson.fromJson(gson.toJson(object), new TypeToken<PositionsChannelApplicationGroups>(){}.getType());

но это дает мне следующее исключение (ниже).
Что я делаю неправильно ?

com.google.gson.JsonParseException: Expecting object found: "MyObj1{hibernateID=0, portfolioName='MyString'}"
    at com.google.gson.JsonObjectDeserializationVisitor.visitFieldUsingCustomHandler(JsonObjectDeserializationVisitor.java:100)
    at com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:63)
    at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120)
    at com.google.gson.JsonDeserializationContextDefault.fromJsonPrimitive(JsonDeserializationContextDefault.java:85)
    at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:56)
    at com.google.gson.MapTypeAdapter.deserialize(MapTypeAdapter.java:67)
    at com.google.gson.MapTypeAdapter.deserialize(MapTypeAdapter.java:33)
    at com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java:51)
    at com.google.gson.JsonDeserializationVisitor.invokeCustomDeserializer(JsonDeserializationVisitor.java:92)
    at com.google.gson.JsonObjectDeserializationVisitor.visitFieldUsingCustomHandler(JsonObjectDeserializationVisitor.java:117)
    at com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:63)
    at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120)

1 Ответ

2 голосов
/ 03 июня 2011

Ограничение Gson, с которым вы сталкиваетесь, связано с тем, как оно сериализует ключи карты: вызывая toString().От MapTypeAdapter:

map.add(String.valueOf(entry.getKey()), valueElement);

Это поведение также описано в документации MapTypeAdapter.

Эта реализация действительно хорошо работает только с простым примитивомвводит в качестве ключа карты.Если ключ не является простым примитивом, тогда объект является {@code toString} ed, и это значение используется в качестве его ключа.

Если вы настаиваете на использовании пользовательских типов в качестве ключей карты, тогда лучше всегоЯ могу сказать, что вам придется написать собственный сериализатор и / или пользовательский десериализатор и / или toString(), который генерирует строковое представление, которое легко десериализовать.

Кроме того, посмотрите на MapAsArrayTypeAdapter для одного подхода.(Его можно использовать с вызовом GsonBuilder.enableComplexMapKeySerialization(), а не с помощью прямой реализации, как описано в документации (потому что в настоящее время это не публичный класс). Я не проверял его, чтобы увидеть, работает ли его реализация, но выглядит многообещающе.)

Примечание: атрибуты applicationIdToPortfolios и applicationIdToAccounts сериализуются и десериализуются просто без пользовательской обработки, поскольку они являются картами с ключами примитивного типа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...