2016-07-15 2 views
0

Я получаю JSON, который имеет следующую структуру:Gson десериализации с изменением типов полей

{"field1": "string", 
"field2": false, 
"a": { 
    "b": { 
     "listString": [] 
    }, 
    "c": { 
     "listString": [], 
     "s": "string" 
    }, 
    "parent": { 
     "childA": { 
      "listString": ["string", "string"] 
     }, 
     "s": "string" 
    }, 
    "parent2": { 
     "listString": ["string", "string"], 
     "s": "string" 
    } 
}, 
"field3": ["s", "s"] 
} 

Я столкнулся проблемы с parentparent2), так как формат этих полей может измениться. Хотя формат сложных объектов b и c остается неизменным. Например, я могу получить parent (то же справедливо и для parent2) таким образом:

{"parent": { 
    "childA":{ 
     "listString": ["ssssa", "a"] 
     }, 
    "s": "string" 
}} 

или

{"parent": { 
    "listString": ["ssssa", "a"], 
    "s": "string" 
}} 

Кроме того, childA поле (если он существует) может иметь разные названия, это может быть childB или childC

Я создал классы Java для сложных объектов:

public class MyPojo{ 
    private String[] field1; 
    private String field2; 
    private A a; 
    private String field3;...} 

public class A{ 
    private B b; 
    private C c; 
    private Parent parent; 
    private Parent2 parent2;..} 

public class Parent{ 
    private String s; 
    private ChildA childA;...}... 

Как можно десериализовать что-то подобное с Gson, если объекты parent и parent2 имеют разные формы?

+0

есть ребенокA, ребенокB и childC - единственные возможности? или это может быть что угодно с префиксом ребенка *? например childXX? – gybandi

+0

Чтобы быть более точным, childA, childB и childC (если существуют) должны быть AND, OR, NOT. И это единственные имена элементов, которые могут возникнуть. – choka

ответ

0

Это родительский класс:

public class Parent { 
Map<String, JsonElement> parent = null; 

public Map<String, JsonElement> getParent() { 
    return parent; 
} 

public void setParent(Map<String, JsonElement> parent) { 
    this.parent = parent; 
} 

} 

Это главный класс:

public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    String input = "{\"parent\": {\"s\": \"string\",\"childA\":{\"listString\": [\"ssssa\", \"a\"]}}}"; 
    Gson gsonInstance = null; 

    gsonInstance = new GsonBuilder().create(); 

    Parent p = gsonInstance.fromJson(input, Parent.class); 

    Map<String, JsonElement> parentMap = p.getParent(); 
    Set<String> keyMap = parentMap.keySet(); 

    Iterator<String> iter = keyMap.iterator(); 
    while(iter.hasNext()){ 
     String name = iter.next(); 
     if(name.matches("child(.*)")){ 
      System.out.println(parentMap.get(name)); 
      // do your logic 
     } 
     if (keyMap.contains("listString")){ 
      List<String> listString = getListString(parentMap.get("listString")); 
      System.out.println(listString.toString()); 
     } 
    } 

} 

public static List<String> getListString(JsonElement list){ 
    Type listType = new TypeToken<List<String>>() {}.getType(); 
    List<String> listString = new Gson().fromJson(list, listType); 
    return listString; 
} 

Надеется, что это помогает!

+0

Спасибо! Это помогает и хорошо работает для этого примера! Однако мой JSON более сложный, а поле ** parent ** - только одна его часть. Возможно ли создать пользовательский десериализатор, который будет основываться на значениях, присутствующих на карте (поэтому либо (объект «childA», либо «s») или (массив «listString» и «s»)), конвертировать все свойства для соответствующего родительского Java ** объекта **? – choka

+0

Я думаю, вы должны упомянуть об этом в вопросе. Если вам нужен более общий ответ для сложного класса, вы можете обратиться к аналогичной проблеме здесь: http://stackoverflow.com/questions/38226024/gson-with-several-known-classes/38321215#38321215 –

+0

Спасибо! Я соответствующим образом обновил свой вопрос. – choka

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