Retrofit 2: response.body() is null, but status code is 200

10,747

I think there's a mistake in your model.

Try:

public class StackQuestions {
    @SerializedName("items")
    List<StackQuestion> questions;
}
Share:
10,747
Nelson
Author by

Nelson

Updated on June 08, 2022

Comments

  • Nelson
    Nelson almost 2 years

    I'm not sure why this is happening, I am trying to get data from:

    https://api.stackexchange.com/2.2/questions?order=desc&sort=creation&site=stackoverflow&tagged=android
    

    Using the following code:

    public interface StackOverflowAPI {
    
        @GET("/2.2/questions?order=desc&sort=creation&site=stackoverflow")
        Call<StackQuestions> loadQuestions(@Query("tagged") String tags);
    
    }
    

    and classes:

    public class StackQuestion {
    
        @SerializedName("title")
        private String title;
    
        @SerializedName("view_count")
        private int numViews;
    
        @SerializedName("is_answered")
        private boolean solved;
    
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public int getNumViews() {
            return numViews;
        }
    
        public void setNumViews(int numViews) {
            this.numViews = numViews;
        }
    
        public boolean isSolved() {
            return solved;
        }
    
        public void setSolved(boolean solved) {
            this.solved = solved;
        }
    
    }
    
    
    public class StackQuestions {
        List<StackQuestion> questions;
    }
    

    fragment:

    public class AlphaFragment extends Fragment implements Callback<StackQuestions> {
    
        private StackOverflowAPI stackOverflowAPI;
    
        private EditText    etxtQuestionToSearch;
        private Button      btnSearchQuestion;
    
        private RecyclerView                mRecyclerView;
        private RecyclerView.Adapter        mStackQuestionsAdapter;
        private RecyclerView.LayoutManager  mLayoutManager;
    
        private ArrayList<StackQuestion> mStackQuestionsList;
    
        private final static String TAG = "AlphaFragment";
    
        public AlphaFragment() {}
    
    
        // ------------------------ FRAGMENT LIFECYCLE ------------------------ //
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            init();
        } // end : onCreate Method
    
        @Override
        public View onCreateView(LayoutInflater inflater,
                                 ViewGroup container,
                                 Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_alpha, container, false);
    
            etxtQuestionToSearch = (EditText) view.findViewById(R.id.etxt_stack_topic);
            btnSearchQuestion = (Button) view.findViewById(R.id.button_stack_search);
            mRecyclerView = (RecyclerView) view.findViewById(R.id.rcvw_stackquestions_list);
    
            // Recycler View SETUP
            mLayoutManager = new LinearLayoutManager(getActivity());
            mRecyclerView.setLayoutManager(mLayoutManager);
            mRecyclerView.setItemAnimator(new DefaultItemAnimator());
    
            btnSearchQuestion.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    searchStackQuestion();
                } // end : onClick Method
            });
    
            return view;
        } // end : onCreateView Method
    
    
        // ------------------------- CALLBACK METHODS ------------------------- //
    
        @Override
        public void onResponse(Call<StackQuestions> call,
                               Response<StackQuestions> response) {
            if (response == null) {
                return;
            }
    
            List<StackQuestion> resultList = response.body().questions;
    
            // X:ERROR: .questions == NULL, so Toast appears
            if (resultList == null || resultList.isEmpty()) {
                Toast.makeText(getActivity(), "Results for the query are null/empty", Toast.LENGTH_LONG).show();
                return;
            }
    
            // Add resulting data from web service
            for (StackQuestion question : resultList) {
                mStackQuestionsList.add(question);
            }
    
            // Assign data to recycler view
            mStackQuestionsAdapter = new StackQuestionsAdapter(
                mStackQuestionsList,
                getActivity(),
                new RVTapListener() {
                    @Override
                    public void onItemClick(View v, int position) {
                        Toast.makeText(getActivity(), "Now clicked, but not implemented " + new Date(), Toast.LENGTH_SHORT).show();
                    } // end : onItemClick Method
                }
            );
            mRecyclerView.setAdapter(mStackQuestionsAdapter);
        } // end : onResponse Method
    
        @Override
        public void onFailure(Call<StackQuestions> call,
                              Throwable t) {
            Toast.makeText(getActivity(), t.getLocalizedMessage(), Toast.LENGTH_LONG).show();
        } // end : onFailure Method
    
    
        // ------------------------- FRAGMENT METHODS ------------------------- //
    
        private void init() {
            Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
                .create();
    
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
    
            Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.stackexchange.com")
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(client)
                .build();
    
            stackOverflowAPI = retrofit.create(StackOverflowAPI.class);
        } // end : init Method
    
        private void searchStackQuestion() {
            mStackQuestionsList = new ArrayList<>();
    
            Call<StackQuestions> call = stackOverflowAPI.loadQuestions("android");
            call.enqueue(this);
        } // end : searchStackQuestion Method
    
    }    
    

    Gradle dependencies:

    compile 'com.google.code.gson:gson:2.7'
    compile 'com.android.support:design:24.0.0'
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.android.support:cardview-v7:24.0.0'
    compile 'com.android.support:appcompat-v7:24.0.0'
    compile 'com.android.support:recyclerview-v7:24.0.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'
    

    After executing the code, I've got on logcat, the following:

    D/OkHttp: <-- 200 OK https://api.stackexchange.com/2.2/questions?order=desc&sort=creation&site=stackoverflow&tagged=android (1136ms)
    D/OkHttp: Cache-Control: private
    D/OkHttp: Content-Type: application/json; charset=utf-8
    D/OkHttp: Access-Control-Allow-Origin: *
    D/OkHttp: Access-Control-Allow-Methods: GET, POST
    D/OkHttp: Access-Control-Allow-Credentials: false
    D/OkHttp: X-Content-Type-Options: nosniff
    D/OkHttp: Date: Tue, 28 Jun 2016 22:56:26 GMT
    D/OkHttp: {"items":[{"tags":["android"],"owner":{"reputation":1,"user_id"  ...
    D/OkHttp: er_id":1163471,"user_type":"registered","accept_rate":93,"profil ...
    D/OkHttp: e?type=large","display_name":"Vahid Zadeh","link":"http://stacko ...
    D/OkHttp: n_id":38086882,"link":"stackoverflow.com/questions/380868 ...
    D/OkHttp: ","animation-listener"],"owner":{"reputation":23,"user_id":43462 ...
    D/OkHttp: <-- END HTTP (19295-byte body)
    

    Everything is going fine, but i get NullPointerException in this part of the AlphaFragment:

    List<StackQuestion> resultList = response.body().questions;
    
    // X:ERROR: .questions == NULL, so Toast appears
    if (resultList == null || resultList.isEmpty()) {
        Toast.makeText(getActivity(), "Results for the query are null/empty", Toast.LENGTH_LONG).show();
        return;
    }
    

    What could be the problem? I've got status code 200, and there is JSON information right there; but, after trying to retrieve it, NPE appears.

    Thanks in advance...

  • Frank Zappa
    Frank Zappa over 7 years
    I am having the same problem (response code is null but I can see the JSON record in my okHTTP logcat). The rest API I am hitting (googlemaps timezone) has only 1 item to load into an object and that item has only 5 fields. In other words, no array or list is needed. I cannot figure out how to model by object so it gets the data from the API. I have all of this working for another API that uses a LIST. But with this google (non LIST) API I cannot figure out the model. Help!
  • carl
    carl almost 6 years
    I have the same problem retrieving some "now playing" info from a radio station json api. While getting 200 and seeing the json returned properly from okhttp3, retrofit (2.4.0) will always convert this to a EMPTY response. Hope someone has a generic way to solve this problem. Could not find anything in the retrofit documentation.