在Android中使用改造功能解析嵌套的json

时间:2019-06-18 10:09:52

标签: android json nullpointerexception retrofit2

我收到了空指针异常。我想从Quotes Api-https://quotes.rest/中检索随机报价,以显示在我的android应用程序中。我要去哪里错了?

(如果我没有正确提出问题或通过发布问题违反任何规则,我深感抱歉。这是我第一次提出问题)

我创建了必要的POJO,并尝试在MainActivity中检索报价。

    GetDataService service = RetrofitClientInstance.getRetrofitInstance().create(GetDataService.class);

    Call<Example> call = service.getRandomQuote();

    call.enqueue(new Callback<Example>() {
        @Override
        public void onResponse(Call<Example> call, Response<Example> response) {

            String quote = response.body().getContents().getQuotes().get(0).getQuote();
            Log.d(TAG, "onResponse: ************" + quote);
        }

GetDataService

public interface GetDataService {
@GET("/quote/random")
Call<Example> getRandomQuote();
}

POJO-报价

public class Quote {

@SerializedName("quote")
private String quote;

public Quote(String quote) {
    this.quote = quote;
}

public String getQuote() {
    return quote;
}

public void setQuote(String quote) {
    this.quote = quote;
}
}

POJO-内容

public class Contents {

@SerializedName("quotes")
@Expose
private List<Quote> quotes;


public List<Quote> getQuotes() {
    return quotes;
}

public void setQuotes(List<Quote> quotes) {
    this.quotes = quotes;
}
}

POJO-示例

public class Example {

@SerializedName("contents")
@Expose
private Contents contents;

public Contents getContents() {
    return contents;
}

public void setContents(Contents contents) {
    this.contents = contents;
}
}

RetrofitClientInstance类

public class RetrofitClientInstance {

private static Retrofit retrofit = null;
private static  final String BASE_URL = "https://quotes.rest";

public static Retrofit getRetrofitInstance(){
    if(retrofit == null){
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    return retrofit;
}
}

我希望输出是此Quotes Api(https://quotes.rest/)中的随机报价,但是我收到了Null Pointer Exception。以下是错误-

java.lang.NullPointerException: Attempt to invoke virtual method 'com.platinumstudio.contactsdemo7.network.Contents com.platinumstudio.contactsdemo7.Example.getContents()' on a null object reference
    at     com.platinumstudio.contactsdemo7.MainActivity$3.onResponse(MainActivity.java)

4 个答案:

答案 0 :(得分:1)

您在此处使用的API是this。如API文档所述,获取数据需要API密钥。由于您未在代码中添加API密钥,因此应返回HTTP Status Code中的401失败的响应。

并且始终是最佳实践,在继续对接收到的数据执行操作之前,请检查响应是否成功,以避免应用程序出现崩溃问题。从API提取数据时,请始终保留以下代码段:

call.enqueue(new Callback<Example>() {
        @Override
        public void onResponse(Call<Example> call, Response<Example> response) {
                if(response.isSuccessful && response.body() != null){
                    //Get contents & quote
                }
                else {
                    //Check response code & show the relevant error message through Toast or Dialog
                }
        }

        @Override
        public void onFailure(Call call, Throwable t) {
                //Show a failed message to the user
        }
}

答案 1 :(得分:0)

我认为您需要在请求中添加Api密钥,否则将不允许您访问数据。因此,您的响应的正文为null,这将导致崩溃。如网站上所述:

For using the private end points and subscribing to the API please visit https://theysaidso.com/api.

答案 2 :(得分:0)

https://theysaidso.com/api/ 在API网站上,您会找到用于访问随机报价的链接

这是链接:

http://quotes.rest/quote/random.json?api_key=

没有密钥,您将获得未经授权的访问

答案 3 :(得分:0)

此API需要Authorization key才能访问数据。因此,如下所示修改界面GetDataService

public interface GetDataService {
@GET("/quote/random/")
Call<Example> getRandomQuote(@HeaderMap Map<String, String> headerMap);

}

//HeaderMap will have authorization key and its value as <Key,Value> pair.