【问题标题】:Retrofit response returning null in Android在Android中返回null的改造响应
【发布时间】:2017-12-23 04:55:54
【问题描述】:

我想显示来自 JSON 值的文本。我正在使用Retrofit 拨打API 电话我不知道我是否做得对。无论如何,这是我的代码。

这是网址链接:http://api.icndb.com/jokes/random

网站每次都会随机显示一个笑话。以下是网站输出的示例:

{ "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);

}

模型类

public class Api {

    @SerializedName("joke")
    private String joke;

    public String getJoke() {
        return joke;
    }

    public void setJoke(String joke){
        this.joke = joke;
    }
}

【问题讨论】:

  • 确保您已在清单中添加 INTERNET 权限
  • 谢谢,但它已经启用了。
  • 看起来您的模型类不太正确。看看 Navaneet 的回答

标签: android retrofit


【解决方案1】:

提供的 json 响应在另一个 json 对象内有一个名为 value 的 json 对象(格式为 {..,"value":{}})。所以我们需要两个模型类——一个用于outer json object,另一个用于inner json object(value)。

你需要有两个这样的模型类

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;
}

下面是值对象

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;
}

}

现在,response.body() 将得到 outer json object(Api) 的结果,response.body().getValue() 将得到 inner json object(Value) 的结果。

现在在你的响应回调中,得到这样的响应

String result = response.body().getValue().getJoke();

还要确保您拥有像这样在清单中声明的​​必要互联网权限

&lt;uses-permission android:name="android.permission.INTERNET" /&gt;

确保您在 app level build.gradle 文件中设置了最新的依赖项

implementation 'com.squareup.retrofit2:retrofit:2.4.0'

implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

【讨论】:

  • 像魅力一样工作,谢谢。我有一个小问题,如何在 GET 请求发送后输出完整的 URL?换句话说,我只想输出完整的 URL,以防 onResponse 出现错误。再次感谢。
  • 究竟是什么错误?假设您的响应不成功,然后在您的onResponse 回调中将您的消息(或要输出的网址)添加为if(!response.isSuccess()){ } 内的吐司
【解决方案2】:

正如@Aswin 建议和@Navneet 回答的那样,您的 POJO 课程有问题。 我建议你使用jsonschema2pojoRoboPOJOGenerator 这样下次你就避免遇到这种错误了。

步骤

1) 转至http://www.jsonschema2pojo.org/

2) 将您的回复粘贴到那里并输入包和类名

3) 选择目标语言为 Java 或 Kotlin(如果您正在使用)

4) 源类型为 Json

5) 注释样式为 Gson

6) 点击预览

7) 将这些类复制并粘贴到您的应用程序包中

【讨论】:

  • 那个网站真的很有帮助,非常感谢。
【解决方案3】:

它们是您正在使用的模型类中的问题。

api 的响应是:

{
"type": "success",
"value": {
    "id": 429,
    "joke": "Chuck Norris has never been accused of murder because his roundhouse kicks are recognized as &quot;acts of God.&quot;",
    "categories": []
}
}

因此,为了从响应中获取笑话的值作为字符串,您的模型类应该是这样的:

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;
}
}

你的价值等级是:

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;
}
}

现在您可以像这样获得您的价值:

 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();
        }
    });

根据您的要求进行更改。

快乐编码..

【讨论】:

    【解决方案4】:

    在您的AndroidManifest.xml 中添加此权限

    <uses-permission android:name="android.permission.INTERNET" />
    

    将此添加到您的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'
    

    添加这个接口,

    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;
            }
        }
    
    }
    
    
    }
    

    创建 2 个模型类: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;
    }
    
    }
    

    创建价值模型类: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;
    }
    
    }
    

    将此代码添加到您的 Activity onCreate() 方法中

      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) {
    
                    }
                });
    

    【讨论】:

      【解决方案5】:

      不确定这是否是一个好方法,但对我有用

          val json = JSONObject(Gson().toJson(response.body().data)).toString()
      Gson().fromJson(json, User::class.java)
      

      我的回复结构是:

      {
        "success":true,
        "data":{
           "p1":32,
           "p2":34
            },
        "message":""
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-01
        • 1970-01-01
        • 2020-03-06
        相关资源
        最近更新 更多