Simon Olsen
Simon Olsen

Reputation: 775

Android Retrofit troubles

So I am trying to make use of retrofit to pull information from wikipedia. These are the classes with the relevant retrofit code:

https://github.com/smholsen/whatIsThisThing/blob/master/app/src/main/java/com/simon/whatisthisthing/RetrofitBuilder.java

https://github.com/smholsen/whatIsThisThing/blob/master/app/src/main/java/com/simon/whatisthisthing/WikiInfo.java

https://github.com/smholsen/whatIsThisThing/blob/master/app/src/main/java/com/simon/whatisthisthing/WikiService.java

Retrofit doesnt throw any exceptions, but the

Log.i("RetrofitResponse", mResponse.toString());

in the onResponse callback method shows that the returned body just contains null...

Does any of you see any obvious mistakes I've done?

Is this:

interface WikiService {

    @GET("?format=json&action=query&prop=extracts&exintro=&explaintext=")
    Call<WikiInfo> search(@Query("titles") String search);
}

The correct way of denoting this uri? : https://en.wikipedia.org/w/api.php?&action=query&prop=extracts&exintro=&explaintext=&titles=pizza&format=json

How does retrofit know how to map the json fields to my WikiInfo object fields? I gave the fields in the class the same names as the keys in the json response.

I will be very grateful for any response!

Thanks alot in advance.

Best regards

Upvotes: 1

Views: 782

Answers (2)

savepopulation
savepopulation

Reputation: 11921

I think you have a problem about your pojos. Here's an example pojos to get data from wikipedia api with retrofit.

Edit: Main Wrapper class called Result

public class Result {
    @SerializedName("batchcomplete")
    private String result;
    @SerializedName("query")
    private Query query;
}

Query Class:

public class Query {
    @SerializedName("pages")
    private Map<String, Page> pages;

    public Map<String, Page> getPages() {
        return pages;
    }

    public void setPages(Map<String, Page> pages) {
        this.pages = pages;
    }
}

And Page

public class Page {
    @SerializedName("pageid")
    private long id;
    @SerializedName("title")
    private String title;
    @SerializedName("extract")
    private String content;
}

And here's your Services interface:

interface WikiService {
    @GET("?format=json&action=query&prop=extracts&exintro=&explaintext=")
    Call<Result> search(@Query("titles") String search);
}

Basically you need a wrapper class. Wikipedia's json response's labels which you need to match with your Page pojo can be changed. And also number can be changed. So you need to match with a Map to get a successful response with Retrofit.

Here's my example GitHub project with you can see an example implementation with wikipedia api and retrofit.

https://github.com/savepopulation/wikilight

Upvotes: 2

OneCricketeer
OneCricketeer

Reputation: 191743

So, here's the JSON you get back.

{
    "batchcomplete": "",
    "query": {
        "normalized": [{
            "from": "pizza",
            "to": "Pizza"
        }],
        "pages": {
            "24768": {
                "pageid": 24768,
                "ns": 0,
                "title": "Pizza",
                "extract": "Pizza is a yeasted flatbread generally topped with tomato sauce and cheese and baked in an oven. It is commonly topped with a selection of meats, vegetables and condiments. The term was first recorded in the 10th century, in a Latin manuscript from Gaeta in Central Italy. The modern pizza was invented in Naples, Italy, and the dish and its variants have since become popular and common in many areas of the world.\nIn 2009, upon Italy's request, Neapolitan pizza was safeguarded in the European Union as a Traditional Speciality Guaranteed dish. The Associazione Verace Pizza Napoletana (the True Neapolitan Pizza Association) is a non-profit organization founded in 1984 with headquarters in Naples. It promotes and protects the \"true Neapolitan pizza\".\nPizza is sold fresh or frozen, either whole or in portions, and is a common fast food item in Europe and North America. Various types of ovens are used to cook them and many varieties exist. Several similar dishes are prepared from ingredients commonly used in pizza preparation, such as calzone and stromboli."
            }
        }
    }
}

And here's your (stripped-down) Java class.

public class WikiInfo {
    private String name;
    private String extract;
}

Retrofit delegates the JSON handling to Gson, which you set here.

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

It is having issues trying to know what you want out of that JSON, and it can't simply know you wanted response["query"]["pages"], then page id #24768, and "title" and "extract" from that.


So, the solution is either

  1. Don't reinvent the wheel. Find a reasonable Java API for Wikipedia or see if an existing Retrofit Wikipedia sample exists. (See WikiLight, for example)
  2. Continue on with what you have, but do some research into how to properly implement your WikiInfo classes. See the Gson documentation to get started with that, but an object with a Map<String, Page> page would be a good start. Then Page.java contains private String title, extract;

Upvotes: 2

Related Questions