2017-02-18 7 views
0

Я хочу десериализации JSON как это:Вложенные объекты JSON в глубоких уровней в модифицированной

{ 
"software": { 
    "info": { 
    "id": "1", 
    "name": "نرم اقزار", 
    "type": "complex" 
    }, 

    "sub": { 
    "windows": { 
     "info": { 
     "id": "2", 
     "name": "ویندوزی", 
     "type": "complex" 
     }, 
     "sub": { 
     "photoshop": { 
      "info": { 
      "id": "3", 
      "name": "فوتوشاپ", 
      "type": "product" 
      } 
     }, 
     "word": {...} 
     , 
     "matlab": {...} 
     } 
    } 
    }, 
    "ios": {...}, 
    "linux": {...} 
} 
} 
} 

для этого в Retrofit я запрограммировал некоторые модели, как это:

Root.java

public class Root { 

    public Software software; 
} 

Software.java

public class Software { 

    public Info info; 
    public Sub sub; 
} 

Info.java

public class info { 

    public int id; 
    public String name; 
    public String type; 
} 

Sub.java

public class sub { 

    public Software software; 
} 

предположим, все добытчика и сеттеры в классах.

мой интерфейс:

ServicesAPI.java

public interface ServicesAPI { 

@GET("services.php") 
Call<Root> getSofwares(); 

}

и, наконец, моя MainActivity это:

Gson gson = new GsonBuilder() 
      .setLenient() 
      .create(); 

    Retrofit retrofit = new Retrofit.Builder() 
      .baseUrl(BASE_URL) 
      .addConverterFactory(GsonConverterFactory.create(gson)) 
      .build(); 

    ServicesAPI servicesAPI = retrofit.create(ServicesAPI.class); 

    Call<Root> call = servicesAPI.getSofwares(); 
    call.enqueue(new Callback<Root>() { 
     @Override 
     public void onResponse(Call<Root> call, Response<Root> response) { 
      //some codes 
     } 

     @Override 
     public void onFailure(Call<Root> call, Throwable t) { 
      // 
     } 
    }); 

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

this is the response

+0

Возможно, это может быть вызвано рекурсивным определением (не имеет никакого отношения к тому, чтобы быть на 3-м уровне)? – muratgu

+0

точно я хочу быть рекурсивным. конечно, я тестировал несколько разных классов вместо «Software». например, 'SoftwareInLevelTwo'. но он был снова «null» – MHSFisher

ответ

0

Имена классов должны быть написаны в верхнем регистре.

В вашем случае это будет

public class Root { 
    private Software software; 
    private Sub sub; 
    private Ios ios; 
    // .... and so on 
} 

Поскольку имя юг, но данные разные, вы можете создать еще одну модель, как

public class SubData { 
    SubInfo info; 

    class SubInfo { 
     private int id; 
     private String name; 
     private String type; 
    } 
} 

Вашего класс Sub может выглядеть, что

public class Sub { 
    private Map<String, SubData> sub; 
    private SubData windows; 
} 

Для этого вам необходимо использовать карту, чтобы gson (de) сериализовал ее для вас. Если эти данные еще не известны, вы можете использовать собственный десериализатор и проверить, является ли «ключ» JsonObject или String.

+0

на втором уровне, объекты 'sub' могут быть бесконечными. Я хочу иметь все объекты. например, я не могу создавать 'windows' или' ios' в качестве полей в моей модели. потому что это могут быть бесконечные поля. – MHSFisher

+0

В этом случае вы создадите пользовательский десериализатор и «validae», если Object является объектом JSONObject. –

0

Данный JSON выглядит иметь противоречивую структуру: $.software.sub.windows, но $.software.ios и $.software.linux недостающие промежуточный sub собственности. Предполагая, что последние два должны быть, вероятно, вложены непосредственно в $.software.sub, так как windows (подобно всей структуре его потомков) вам просто не нужен класс Sub: он не может быть таким полиморфным, как вы ожидаете, , Причина того, почему вы получаете null, - это то, что ваш JSON на пути $.software.sub.windows (а также ios и linux) не отображаются правильно: Software.sub ожидает, что ваш документ JSON будет иметь поле с именем sub.Все, что вам нужно это просто модифицируя Software класс как это:

final class Software { 

    Info info; 
    Map<String, Software> sub; // previously `public Sub sub;` 

} 

После этого вы можете разобрать ваш JSON и легко пройти через объект анализируемой:

final Root root = gson.fromJson(JSON, Root.class); 
System.out.println(root.software.sub.get("windows").sub.get("photoshop").info.name); 

Выход:

فوتوشاپ

+0

Неверные предположения о несогласованности? System.out? Прямое взаимодействие с Gson? Сломанный вывод в терминале, отличном от Unicode, для арабского скрипта? В самом деле, где я ошиблась? –

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