как распарсить json

694
19 сентября 2017, 06:57

Работаю с wiki api, моя задача получить url страницы по id. Использую retrofit2. Вот запрос с которым я работаю [https://ru.wikipedia.org/w/api.php?&action=query&list=&prop=info&inprop=url&format=json&pageids=2549076|744563|4409887] моя проблема в том, что мне приходит json и я не могу его сериализовать, так как мне POJO конвертирует имена классов в виде цифр из id

    {
"batchcomplete": "",
"query": {
    "pages": {
        "744563": {
            "pageid": 744563,
            "ns": 0,
            "title": "Львовский оперный театр",
            "contentmodel": "wikitext",
            "pagelanguage": "ru",
            "pagelanguagehtmlcode": "ru",
            "pagelanguagedir": "ltr",
            "touched": "2017-09-16T20:57:05Z",
            "lastrevid": 87226524,
            "length": 14547,
            "fullurl": "https://ru.wikipedia.org/wiki/%D0%9B%D1%8C%D0%B2%D0%BE%D0%B2%D1%81%D0%BA%D0%B8%D0%B9_%D0%BE%D0%BF%D0%B5%D1%80%D0%BD%D1%8B%D0%B9_%D1%82%D0%B5%D0%B0%D1%82%D1%80",
            "editurl": "https://ru.wikipedia.org/w/index.php?title=%D0%9B%D1%8C%D0%B2%D0%BE%D0%B2%D1%81%D0%BA%D0%B8%D0%B9_%D0%BE%D0%BF%D0%B5%D1%80%D0%BD%D1%8B%D0%B9_%D1%82%D0%B5%D0%B0%D1%82%D1%80&action=edit",
            "canonicalurl": "https://ru.wikipedia.org/wiki/%D0%9B%D1%8C%D0%B2%D0%BE%D0%B2%D1%81%D0%BA%D0%B8%D0%B9_%D0%BE%D0%BF%D0%B5%D1%80%D0%BD%D1%8B%D0%B9_%D1%82%D0%B5%D0%B0%D1%82%D1%80"
        },
        "2549076": {
            "pageid": 2549076,
            "ns": 0,
            "title": "Крепость Святой Елисаветы",
            "contentmodel": "wikitext",
            "pagelanguage": "ru",
            "pagelanguagehtmlcode": "ru",
            "pagelanguagedir": "ltr",
            "touched": "2017-09-15T05:33:34Z",
            "lastrevid": 87632281,
            "length": 5055,
            "fullurl": "https://ru.wikipedia.org/wiki/%D0%9A%D1%80%D0%B5%D0%BF%D0%BE%D1%81%D1%82%D1%8C_%D0%A1%D0%B2%D1%8F%D1%82%D0%BE%D0%B9_%D0%95%D0%BB%D0%B8%D1%81%D0%B0%D0%B2%D0%B5%D1%82%D1%8B",
            "editurl": "https://ru.wikipedia.org/w/index.php?title=%D0%9A%D1%80%D0%B5%D0%BF%D0%BE%D1%81%D1%82%D1%8C_%D0%A1%D0%B2%D1%8F%D1%82%D0%BE%D0%B9_%D0%95%D0%BB%D0%B8%D1%81%D0%B0%D0%B2%D0%B5%D1%82%D1%8B&action=edit",
            "canonicalurl": "https://ru.wikipedia.org/wiki/%D0%9A%D1%80%D0%B5%D0%BF%D0%BE%D1%81%D1%82%D1%8C_%D0%A1%D0%B2%D1%8F%D1%82%D0%BE%D0%B9_%D0%95%D0%BB%D0%B8%D1%81%D0%B0%D0%B2%D0%B5%D1%82%D1%8B"
        },
        "4409887": {
            "pageid": 4409887,
            "ns": 0,
            "title": "Памятник Ленину (Львов)",
            "contentmodel": "wikitext",
            "pagelanguage": "ru",
            "pagelanguagehtmlcode": "ru",
            "pagelanguagedir": "ltr",
            "touched": "2017-09-16T16:12:47Z",
            "lastrevid": 83520554,
            "length": 6170,
            "fullurl": "https://ru.wikipedia.org/wiki/%D0%9F%D0%B0%D0%BC%D1%8F%D1%82%D0%BD%D0%B8%D0%BA_%D0%9B%D0%B5%D0%BD%D0%B8%D0%BD%D1%83_(%D0%9B%D1%8C%D0%B2%D0%BE%D0%B2)",
            "editurl": "https://ru.wikipedia.org/w/index.php?title=%D0%9F%D0%B0%D0%BC%D1%8F%D1%82%D0%BD%D0%B8%D0%BA_%D0%9B%D0%B5%D0%BD%D0%B8%D0%BD%D1%83_(%D0%9B%D1%8C%D0%B2%D0%BE%D0%B2)&action=edit",
            "canonicalurl": "https://ru.wikipedia.org/wiki/%D0%9F%D0%B0%D0%BC%D1%8F%D1%82%D0%BD%D0%B8%D0%BA_%D0%9B%D0%B5%D0%BD%D0%B8%D0%BD%D1%83_(%D0%9B%D1%8C%D0%B2%D0%BE%D0%B2)"
        }
    }
}

и я не могу его сериализовать, так как мне POJO конвертирует имена классов в виде цифр из id

public class _4409887 implements Serializable
{
@SerializedName("pageid")
@Expose
private Integer pageid;
@SerializedName("ns")
@Expose
private Integer ns;
@SerializedName("title")
@Expose
private String title;
@SerializedName("contentmodel")

Такие запросы посылаются каждые 5 секунд и количество id динамическое от 0 до 5. Моя задача распарсить json и получить из него значение "fullurl" Вот мой код

   synchronized public List<Geosearch> getPagesId() {
    WikiApi service = getRetrofit().create(WikiApi.class);
    Call<ResponseBodyWiki> responseBodyCall =
            service.getArticleId(Constants.WIKI_ACTION,
                    Constants.WIKI_LIST,
                    Constants.TEMP_COORD,
                    Constants.RADIUS_SEARCH_WIKI,
                    Constants.LIMIT_ARTICLE_WIKI,
                    Constants.JSON);
    responseBodyCall.enqueue(new Callback<ResponseBodyWiki>() {
        @Override
        public void onResponse(Call<ResponseBodyWiki> call, Response<ResponseBodyWiki> response) {
            Log.d("+++", "response ok id");
            if (response.isSuccessful() && response.body().getQuery().getGeosearch().size() > 0) {
                geoSearch = response.body().getQuery().getGeosearch();
                Log.d("+++", "geoSearch " + geoSearch.size());
                getWikiUrl(geoSearch);
            }
        }
        @Override
        public void onFailure(Call<ResponseBodyWiki> call, Throwable t) {
            Log.d("+++", "onFailure result NO");
            Log.d("+++", String.valueOf(t));
        }
    });
    return geoSearch;
}
private Retrofit getRetrofit() {
    Gson gson = new GsonBuilder().create();
    return new Retrofit.Builder()
            .baseUrl(Constants.WIKI_BASE_URL)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build();
}
private void checkStartNewUpdate() {
    cycleRunnable();
}
synchronized public void getWikiUrl(List<Geosearch> geoSearch) {
    String [] tmpPagesId = new String[geoSearch.size()];
    for (int i = 0; i < geoSearch.size(); i++) {
        if(i < geoSearch.size() - 1)
            tmpPagesId[i] = (String.valueOf(geoSearch.get(i).getPageid()) + "|");
        else tmpPagesId[i] = (String.valueOf(geoSearch.get(i).getPageid()));
        Log.d("+++", "pagesId " + tmpPagesId[i]);
    }

    WikiApi service = getRetrofit().create(WikiApi.class);
    Call<ResponseBody> responseBodyCall =
            service.getArticle(Constants.WIKI_ACTION,
                    Constants.WIKI_INFO,
                    Constants.WIKI_URL,
                    Constants.JSON,
                    tmpPagesId);
    responseBodyCall.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        Log.d("+++", "response url id ");
        if(response.isSuccessful()) {
            try {
                Log.d("+++", response.body().string());
                checkStartNewUpdate();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        Log.d("+++", "onFailure result NO");
        Log.d("+++", String.valueOf(t));
        checkStartNewUpdate();
    }
});

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

    @GET("/w/api.php?")
Call<ResponseBody> getArticle(
        @Query("action") String action,
        @Query("prop") String INFO,
        @Query("inprop") String URL,
        @Query("format") String JSON,
        @Query("pageids") String... list);
Answer 1

Судя по всему внутри pages у вас ключи объектов являются ID-шниками какими-то и их имена заранее не известны. В этом случае вам надо указать в модели чтобы они представлялись в виде Map<Integer, ClassModelForContent> - тогда их названия могут быть любыми и обращаться к ним можно будет в коде как к ключам-значениям. Т.е. модель для всего JSON должна как-то так выглядеть:

public class JsonModel {
    public Map<Integer, InnerModel> query;
}
public class InnerModel {
    public Integer pageid;
    public Integer ns;
    public String title;
    public String fullUrl;
}

И потом обращаться к нужному элементу можно как-то так:

for(InnerModel innerModel: response.query.values()){
    System.out.println(innerModel.fullUrl);
}
READ ALSO
Перевод unix time в date

Перевод unix time в date

Помогите разобраться с отрисовкой графиков через graph viewИмеется время в unix time

546
Проверка permissions на телефонах Xiaomi для API&lt;23

Проверка permissions на телефонах Xiaomi для API<23

Как известно у Xiaomi есть своя система разрешений и работает она до 6 андроида, где новая система запроса разрешений появилась повсеместноЯ...

388
Eclipse RCP создание нового окна

Eclipse RCP создание нового окна

В главном окне (которое появляется после запуска приложения) я должен сделать главное меню, в нем должен быть раздел window, в этом разделе я должен...

251
Java. containsAll для списка массивов

Java. containsAll для списка массивов

Есть список, состоящий из массивов ArrayList<int[]> list1;И второй список поменьше ArrayList<int[]> list2;

279