可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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;
}
}
回答1:
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'
回答2:
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
回答3:
Their is a problem in your model class which you are using.
The response of api is :
{
"type": "success",
"value": {
"id": 429,
"joke": "Chuck Norris has never been accused of murder because his roundhouse kicks are recognized as "acts of God."",
"categories": []
}
}
So for getting value of joke from response as a string your model class should be like this :
public class Api implements Serializable {
@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 your Value Class is :
public class Value implements Serializable
{
@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;
}
}
And now you can get your value like this :
call1.enqueue(new Callback<Api>() {
@Override
public void onResponse(Call<Api> call, Response<Api> response) {
if (response.isSuccessful()) {
String jokeValue = response.body().getValue().getJoke();
}
}
@Override
public void onFailure(Call<Api> call, Throwable t) {
t.printStackTrace();
}
});
Do changes as per you requirement.
Happy Coding..
回答4:
Add this permission in your AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
Add this in your build.gradle (Module:app)
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.google.code.gson:gson:2.8.2'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
Add this interface ,
public interface ApiInterface {
public static final String BASE_URL = "http://api.icndb.com";
@GET("/jokes/{random}")
Call<Api> GetApiResponse(@Path("random") String random);
public class ApiClient {
public static ApiInterface apiInterface;
public static ApiInterface getApiInterface() {
if (apiInterface == null) {
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
apiInterface = retrofit.create(ApiInterface.class);
return apiInterface;
} else {
return apiInterface;
}
}
}
}
Create 2 Model Class : com.example.app.Api.java
package com.example.app;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Api {
@SerializedName("type")
@Expose
private String type;
@SerializedName("value")
@Expose
private Value value;
public String getType() {
return type;
}
public Value getValue() {
return value;
}
}
Create Value Model Class : com.example.app.Value.java
package com.example.app;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Value {
@SerializedName("id")
@Expose
private Integer id;
@SerializedName("joke")
@Expose
private String joke;
public int getId() {
return id;
}
public String getJoke() {
return joke;
}
}
Add this code in your Activity onCreate()
Method
ApiInterface.ApiClient.getApiInterface().GetApiResponse('random').enqueue(new Callback<Api>() {
@Override
public void onResponse(Call<Api> call, Response<Api> response) {
String Joke=response.body.getValue().getJoke();
Toast.makeText(MainActivity.this, Joke, Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<Api> call, Throwable t) {
}
});