I wanted to display a text from a JSON
value. I'm using Retrofit
to make API
call I don't know if I'm doing it right. Anyway here's my code.
Here's the url link: http://api.icndb.com/jokes/random .
The website will display a random joke each time. Here's the example of an output from the website:
{ "type": "success", "value": { "id": 175, "joke": "When Chuck Norris was a baby, he didn't suck his mother's breast. His mother served him whiskey, straight out of the bottle.", "categories": [] } }
fragment.java
String url = "http://api.icndb.com/";
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
RetroFitHelper client = retrofit.create(RetroFitHelper.class);
Call<Api> call = client.findJoke("random");
call.enqueue(new Callback<Api>() {
@Override
public void onResponse(Response<Api> response, Retrofit retrofit) {
String result = response.body().getJoke();
Toast.makeText(getContext()," The word is: " + result ,Toast.LENGTH_LONG).show();
}
@Override
public void onFailure(Throwable t) {
Toast.makeText(getContext()," Error..." ,Toast.LENGTH_LONG).show();
}
});
RetroFitHelper.java
public interface RetroFitHelper {
@GET("/jokes/{random}")
Call<Api> findJoke(@Path("random") String random);
}
Model class
public class Api {
@SerializedName("joke")
private String joke;
public String getJoke() {
return joke;
}
public void setJoke(String joke){
this.joke = joke;
}
}
The provided json response has a json object named value
inside another json object(It is of the form {..,"value":{}}
). So we need two model classes - one for the outer json object
and another one for the inner json object
(value).
You will need to have two model classes like this
public class Api {
@SerializedName("type")
@Expose
private String type;
@SerializedName("value")
@Expose
private Value value;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Value getValue() {
return value;
}
public void setValue(Value value) {
this.value = value;
}
and the following one for value object
public class Value {
@SerializedName("id")
@Expose
private Integer id;
@SerializedName("joke")
@Expose
private String joke;
@SerializedName("categories")
@Expose
private List<Object> categories = null;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getJoke() {
return joke;
}
public void setJoke(String joke) {
this.joke = joke;
}
public List<Object> getCategories() {
return categories;
}
public void setCategories(List<Object> categories) {
this.categories = categories;
}
}
Now, response.body()
will have the result of outer json object(Api)
and response.body().getValue()
will have the result for inner json object(Value)
.
Now in your response callback, get response like this
String result = response.body().getValue().getJoke();
Also make sure that you have the necessary internet permission declared in your manifest like this
<uses-permission android:name="android.permission.INTERNET" />
Do ensure you have the latest dependencies setup in your
app level
build.gradle
file
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
As @Aswin suggest and @Navneet answered you have problem in your POJO class. I suggest you to use jsonschema2pojo or RoboPOJOGenerator so next time you avoid to stuck this kind of error.
Steps
1) Go to http://www.jsonschema2pojo.org/
2) Paste your response over there and enter package and class name
3) Choose target language as Java or Kotlin(if you are using)
4) Source type as Json
5) Annotation style as Gson
6) Click Preview
7) Copy and paste those classes to your app package
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With