Как Retrofit 2.0 анализирует вложенный объект JSON?

21

Наша команда решила использовать Retrofit 2.0 , и я делаю некоторые начальные исследования в этой библиотеке. Как указано в названии, я хочу проанализировать некоторые вложенные объекты JSON через Retrofit 2.0 в нашем приложении для Android.

Например, здесь является вложенным объектом JSON с форматом:

{
        "title": "Recent Uploads tagged android",
        "link": "https://www.flickr.com/photos/tags/android/",
        "description": "",
        "modified": "2015-10-05T05:30:01Z",
        "generator": "https://www.flickr.com/",
        "items": [
        {
            "title": ...
            "link": ...
            "media": {"m":"This is the value I want to get:)"}
            "description": ...
            "published": ...
            "author": ...
            "author_id": ...
            "tags": ...
        },
        {...},
        ...
        ]
}

Мне интересны объекты JSON внутри массива items . Я заметил, что есть некоторые сообщения о разборе вложенных объектов JSON через Retrofit 1.X, но последние API-интерфейсы Retrofit 2.0 сильно изменились, что сбивает с толку при адаптации их к новым API-интерфейсам.

Мне приходят в голову два возможных решения:

  1. Напишите мою собственную фабрику конвертеров JSON, которая расширяет Converter.Factory .
  2. >
  3. Возвращает исходный ответ в стиле String и самостоятельно анализирует его. Но нелегко получить исходный ответ от Retrofit 2.0 в соответствии с моими первоначальными исследованиями. Retrofit 2.0, похоже, настаивает на преобразовании ответа на что-то, прежде чем передать его мне, а Retrofit не предоставляет свой собственный StringConverter . (Возможно, я ошибаюсь ~)

Обновление . Мы можем получить исходный ответ, установив JSONElement в качестве pojo для интерфейса API HTTP и используем GSONConverter, предоставленный Retrofit в качестве преобразователя.

Было бы здорово, если бы кто-то мог поделиться некоторыми идеями по этой проблеме.

Спасибо:)

    
задан hackjutsu 05.10.2015 в 08:43
источник
  • Что будет в массиве элементов? Можете ли вы опубликовать эту часть? –  Pankaj Kumar 05.10.2015 в 09:27
  • @PankajKumar Обновлено :) –  hackjutsu 05.10.2015 в 09:34
  • Я добавил ответ, похожий на ваш JSON. Попробуй. –  Pankaj Kumar 05.10.2015 в 09:36
  • @PankajKumar Ницца! Как показано в моем обновленном вопросе, могу ли я определить частный JSONObject media в качестве члена в моем pojo вместо определения нового класса Media, так как значение ключевого носителя также является JSON? –  hackjutsu 05.10.2015 в 09:44
  • Нет. Для этого вам нужен еще один класс. –  Pankaj Kumar 05.10.2015 в 09:45
Показать остальные комментарии

5 ответов

24

Предполагая, что ваш полный JSON выглядит как

{
  "title": "Recent Uploads tagged android",
  "link": "https://www.flickr.com/photos/tags/android/",
  "description": "",
  "modified": "2015-10-05T05:30:01Z",
  "generator": "https://www.flickr.com/",
  "items": [
    {
      "member1": "memeber value",
      "member2": "member value"
    },
    {
      "member1": "memeber value",
      "member2": "member value"
    }
  ]
}

Итак, классы Pojo были бы

public class MainPojo {
    private String title; 
    private String description;
    private String link;
    private String generator;
    private String modified;
    private ArrayList<Items> items;

    // Getters setters
}

public class Items {
    private String member2;
    private String member1;

    // Getters setters
}

Примечание: Это похожее решение для вашего JSON. Члены Item.java могут быть изменены, если у JSON есть другие ключи.

Обновление для Pojo как нового JSON

public class Items {
    private String tags;
    private String author;
    private String title;
    private String description;
    private String link;
    private String author_id;
    private String published;
    private Media media;

    // Getters and Setters
}

public class Media {
    private String m;
    // Getters and Setters
}
    
ответ дан Pankaj Kumar 05.10.2015 в 09:33
источник
  • @IgorGanapolsky См. обновленный раздел. Это был пример кода. –  Pankaj Kumar 23.02.2016 в 06:45
  • работает для запроса запроса, в случае почтового запроса я получаю внутренний объект как null. Вы можете объяснить об этом? –  Pushpendra 26.04.2016 в 14:27
  • @Spartan Я тебя не понял. Лучше, если вы зададите новый вопрос с JSON, в котором вы столкнулись с проблемой. Нет никакого отношения к запросу GET / POST с этим ответом. –  Pankaj Kumar 26.04.2016 в 16:08
5

Следующий код поможет получить вложенный json-объект и массив

, например: json

{  
    "similar_product":[  
        {  .....
}
    ],
    "options":{  
        "Blouse Length":[  
            {  "value_id":"696556",
               }

Сначала нам нужно создать класс модели, имена элементов класса модели одинаковы в json item, мы можем использовать @SerializedName("for exact json name")

public class Product {

       public Options options;

    public void setOptions(Options options) {
        this.options = options;
    }

    public Options getOptions() {
        return options;
    }


    // length...

    public class Options
    {
        @SerializedName("Blouse Length")
        private ArrayList<BlouseLength> blouseLengths;


        public void setBlouseLengths(ArrayList<BlouseLength> blouseLengths) {
            this.blouseLengths = blouseLengths;
        }

        public ArrayList<BlouseLength> getBlouseLengths() {
            return blouseLengths;
        }
    }



    public class BlouseLength {
        String value_id;
        public void setValue_id(String value_id) {
            this.value_id = value_id;
        }



        public String getValue_id() {
            return value_id;
        }
    }

}

создать интерфейс для модификации, чтобы получить элемент json в URL

// don't need to put values of id in retrofit 

ex:: "/api-mobile_.php?method=getProductById&pid="

просто передайте параметр url в запросе, он автоматически извлекает URL

, например:

public interface Retrofit_Api {

    @FormUrlEncoded

    @GET("/api-mobile_.php?method=getProductById")
    Call<Product> responseproduct(@Query("pid") String pid);


}

В вашем основном классе

     String pid=editid.getText().toString();


        final Retrofit adapter = new Retrofit.Builder()
                .baseUrl(Product_url)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        //Creating an object of our api interface
        Retrofit_Api api = adapter.create(Retrofit_Api.class);


        Call<Product> call = api.responseproduct(pid);


        call.enqueue(new Callback<Product>() {
            @Override
            public void onResponse(Call<Product> call, Response<Product> response) {


               ArrayList<Product.BlouseLength> p= new ArrayList(response.body().getOptions().getBlouseLengths());

Editadapter editadapter=new Editadapter(MainActivity.this,p);

                recyclerView.setAdapter(editadapter);


            }

            @Override
            public void onFailure(Call<Product> call, Throwable t) {


                Log.d("Error", t.getMessage());
            }
        });



    }
    
ответ дан lemuriyan 17.08.2016 в 09:33
источник
4

Используйте Gson для простого анализа для ваших моделей Ссылка

Мои помощники:

public String toJson(Object object) {
    return gson.toJson(object);
}

public <T> T fromJson(String json, Class<T> classOfT) {
    return gson.fromJson(json, classOfT);
}

public <T> T fromJson(JsonElement jsonElement, Class<T> classOfT) {
    return gson.fromJson(jsonElement, classOfT);
}
    
ответ дан KP_G 05.10.2015 в 08:47
источник
  • Спасибо :) Можете ли вы рассказать немного о том, как написать интерфейс Retrofit? Что я должен поставить для общего типа T для вызова <T> httpApimethod (...) в HTTP API? Должен ли я определять класс с элементами поля? –  hackjutsu 05.10.2015 в 08:57
  • @Hackjustu, общий тип T будет вашим классом pojo для ответа json. –  Tauqir 05.10.2015 в 09:11
  • Итак, я должен определить класс Java ItemsHolder, который содержит элементы List <Item>. Затем я могу получить экземпляры Item из элементов поля ItemsHolder. Я что-то пропустил? Благодаря:) –  hackjutsu 05.10.2015 в 09:22
  • Вы можете обратиться к этому уроку tutorials.jenkov.com/java-json/gson.html для получения дополнительной информации. –  KP_G 05.10.2015 в 09:28
  • Спасибо за помощь :) –  hackjutsu 05.10.2015 в 22:17
0

Вы пробовали залп? ... я предпочитаю его переоборудовать сейчас, это продукт google. У меня есть рабочий пример, и если вы не возражаете, я могу показать вам. Ссылка

    
ответ дан Goodlife 05.10.2015 в 08:54
источник
  • Спасибо за предложение :) Собственно, наша команда решила использовать Retrofit 2.0, и я делаю некоторые начальные исследования в этой библиотеке. –  hackjutsu 05.10.2015 в 09:00
  • Как волейбол помогает разобрать объекты JSON? –  Igor Ganapolsky 22.02.2016 в 19:35
0

Сала. Я забыл добавить @SerializedName и @Expose аннотаций для внутренних объектов класса и после того, как проблема этих аннотаций решена. Вот так:

JSON:

{"Id": 1,}

и член класса:

@SerializedName("Id")
@Expose
private int id;
    
ответ дан Sayed Abolfazl Fatemi 25.10.2016 в 14:05
источник