Страницы

Поиск по вопросам

понедельник, 3 декабря 2018 г.

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

Работаю с 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 getPagesId() {
WikiApi service = getRetrofit().create(WikiApi.class); Call 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() {
@Override public void onResponse(Call call, Response 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 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) {
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 responseBodyCall = service.getArticle(Constants.WIKI_ACTION, Constants.WIKI_INFO, Constants.WIKI_URL, Constants.JSON, tmpPagesId); responseBodyCall.enqueue(new Callback() {
@Override public void onResponse(Call call, Response 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 call, Throwable t) { Log.d("+++", "onFailure result NO"); Log.d("+++", String.valueOf(t)); checkStartNewUpdate(); } });
Вот мой интерфейс
@GET("/w/api.php?") Call getArticle( @Query("action") String action, @Query("prop") String INFO, @Query("inprop") String URL, @Query("format") String JSON, @Query("pageids") String... list);


Ответ

Судя по всему внутри pages у вас ключи объектов являются ID-шниками какими-то и их имена заранее не известны. В этом случае вам надо указать в модели чтобы они представлялись в виде Map - тогда их названия могут быть любыми и обращаться к ним можно будет в коде как к ключам-значениям. Т.е. модель для всего JSON должна как-то так выглядеть:
public class JsonModel { public Map 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); }

Комментариев нет:

Отправить комментарий