2015-04-09 4 views
0

Я пытался улучшить свой код на этом, но не знаю, каким образом, я получаю JSON это:Пользовательские десериализации с Gson

{ 
"name": "Jhon", 
"lastName": "Smith", 
"clothes": { 
    "gender":"male", 
    "Shirt": { 
     "id": 113608, 
     "name": "Green Shirt", 
     "size": "Large" 
    }, 
    "Pants": { 
     "id": 115801, 
     "name": "Black Leather Pants", 
     "size": "Large" 
     } 
    } 
} 

Как это работает до сих пор имеет как рубашка и Классы штанов, но поскольку они идентичны, я пытаюсь использовать только один класс, который получит оба из них. Я не могу сказать, как генерируется json, поэтому вам придется работать с ним, как он есть.

Это мои классы:

Класс Person

public class Person{ 
    private String lastName; 
    private String name; 
    private Clothes clothes; 
} 

класса Одежда

public class Clothes{ 
    private Shirt Shirt; 
    private Pants pants; 
    private String gender; 
} 

класса Рубашка

public class Shirt{ 
    private String id; 
    private String name; 
    private String size; 
} 

Брюки таким же, как рубашка, дело в том, что я не хочу, чтобы мой код, чтобы сломаться, если/когда они решили добавить еще один кусок одежды, так что я пытаюсь сделать что-то вроде этого

класса Одежда

public class Clothes{ 
    private List<Something> clothList; 
    private String gender; 
} 
+0

Покажите нам, что у вас есть. –

+0

Я думаю, что решение написано в пользовательском классе адаптера. – Raman

ответ

0

Вместо того, чтобы использовать 2 отдельных классов (Shirt и Pants) просто использовать один класс - скажем Cloth. Пробовали так и работал отлично:

Person класс:

package com.dominikangerer.q29550820; 

public class Person { 
    private String name; 
    private String lastName; 
    private Clothes clothes; 
} 

одежды Класс:

package com.dominikangerer.q29550820; 

public class Clothes { 
    private String gender; 
    private Cloth Shirt; 
    private Cloth Pants;   
} 

Ткань Класс:

package com.dominikangerer.q29550820; 

public class Cloth { 
    private Integer id; 
    private String name; 
    private String size; 
} 

После того, как я построил эти классы, я попробовал его прямо в небольшом основном классе, что приводит к совершенно прекрасному десериализации.

Gson g = new Gson(); 
Person person = g.fromJson("{\"name\":\"Jhon\",\"lastName\":\"Smith\",\"clothes\":{\"gender\":\"male\",\"Shirt\":{\"id\":113608,\"name\":\"Green Shirt\",\"size\":\"Large\"},\"Pants\":{\"id\":115801,\"name\":\"Black Leather Pants\",\"size\":\"Large\"}}}", Person.class); 

Не использовать @Expose здесь или @SerializedName("something") потому, что не было необходимости.

Надеюсь, что это поможет вам - иначе, пожалуйста, объясните свою проблему более подробно, и я постараюсь вам помочь.

----------- ------------ Обновление

Хорошо обычно это довольно легко бросить JSon, как вы его там в нормальный Object - но вещь внутри карты (clothes) у вас также есть нормальное значение String. Для этого я предлагаю вам включить функцию Gson@Expose Я расскажу вам, почему это было бы неплохо.

Давайте начнем: я удалил Clothes класс с Map<String, Object> который Gson может легко десериализации - проблема здесь в том, что у нас есть пол внутри этой карты. Я изменил класс Person, который в настоящее время работает как это:

Person v2:

package com.dominikangerer.q29550820; 

public class Person { 
    private String name; 

    private String lastName; 

    @SerializedName("clothes") 
    private Map<String, Object> clothesWrapper; 

    public String getGender() { 
     return clothesWrapper.get("gender").toString(); 
    } 

    public void setGender(String gender) { 
     this.clothesWrapper.put("gender", gender); 
    } 
} 

Теперь мы уже можем картированию gender как String и модифицировать его с геттер и сеттер - еще карту вверх там, где содержится Object s. Следующая вещь, которую мы не хотим, чтобы Map<String, Object> - для десериализации и сериализации это совершенно нормально - но для работы с самим Cloth с - это глупо, так давайте избавиться от него с самым простым способом:

Мы изменим наш класс Person, как это:

Person v3:

package com.dominikangerer.q29550820; 

public class Person { 
    @Expose 
    private String name; 

    @Expose 
    private String lastName; 

    @Expose 
    @SerializedName("clothes") 
    private Map<String, Object> clothesWrapper; 

    private Map<String, Cloth> clothes; 

    public String getGender() { 
     return clothesWrapper.get("gender").toString(); 
    } 

    public void setGender(String gender) { 
     this.clothesWrapper.put("gender", gender); 
    } 

    public Map<String, Cloth> getClothes() { 
     if (clothes == null) { 
      Gson g = new Gson(); 
      clothes = new HashMap<String, Cloth>(); 
      for (Entry<String, Object> entry : clothesWrapper.entrySet()) { 
       if (entry.getKey().equals("gender")) { 
        continue; 
       } 
       String helper = g.toJson(entry.getValue()); 
       Cloth cloth = g.fromJson(helper, Cloth.class); 
       clothes.put(entry.getKey(), cloth); 
      } 
     } 
     return clothes; 
    } 
} 

Как вы можете видеть, мы теперь косвенно бросить все Cloth эс - мы должны делать это так, потому что это самый простой способ получить все LinkedTreeMap к a Cloth - Object без столкновения с ClassCastException. Как вы можете видеть, теперь у нас есть Map<String,Object> clothesWrapper, который позволяет Gson Parse объект (не может найти лучшего имени - извините) и карту Map<String, Cloth> clothes без Expose. Теперь вам также необходимо, чтобы настроить Gson с опцией enableExpose, который работает следующим образом:

(Использование класса Person v3 здесь - просто отлаживать в это - работает как шарм)

public class Main { 
    public static void main(String[] args) { 
     Gson g = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); 
     Person person = g.fromJson("{\"name\":\"Jhon\",\"lastName\":\"Smith\",\"clothes\":{\"gender\":\"male\",\"Shirt\":{\"id\":113608,\"name\":\"Green Shirt\",\"size\":\"Large\"},\"Pants\":{\"id\":115801,\"name\":\"Black Leather Pants\",\"size\":\"Large\"}}}", Person.class); 
     System.out.println(person.getClothes()); 
     System.out.println(person.getGender()); 
    } 
} 

Вы можете найти все классы в этом github repository

+0

A Я вижу :) Я постараюсь добиться этого - дайте мне некоторое время :) – DominikAngerer

+0

Найденное решение - теперь готовьте ответ для вас там – DominikAngerer

+0

Ответ готов служить :) надеюсь, что это на вкус. – DominikAngerer

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