Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrofit Returning Null Response Body

I am trying to make a call to the FlickR API and am having difficulty as the response.body() is returning null.

I am not sure if it relates to my JSON/POJO mapping, but I cannot figure out how to access the response from Retrofit when I make the call to FlickR. I know that my call is being completed successfully as I am actually able to view the JSON through the logging interceptor.

Model:

public class Model {

Photos photos;
int code;
String stat;
String message; // when you text = null

public class Photos {

    @SerializedName("page")
    @Expose
    private int page;
    @SerializedName("pages")
    @Expose
    private int pages;
    @SerializedName("perpage")
    @Expose
    private int perpage;
    @SerializedName("total")
    @Expose
    private String total;
    @SerializedName("photo")
    @Expose
    private List<Photo> photo = new ArrayList<Photo>();

    /**
     * @return The page
     */
    public int getPage() {
        return page;
    }

    /**
     * @param page The page
     */
    public void setPage(int page) {
        this.page = page;
    }

    /**
     * @return The pages
     */
    public int getPages() {
        return pages;
    }

    /**
     * @param pages The pages
     */
    public void setPages(int pages) {
        this.pages = pages;
    }

    /**
     * @return The perpage
     */
    public int getPerpage() {
        return perpage;
    }

    /**
     * @param perpage The perpage
     */
    public void setPerpage(int perpage) {
        this.perpage = perpage;
    }

    /**
     * @return The total
     */
    public String getTotal() {
        return total;
    }

    /**
     * @param total The total
     */
    public void setTotal(String total) {
        this.total = total;
    }

    /**
     * @return The photo
     */
    public List<Photo> getPhoto() {
        return photo;
    }

    /**
     * @param photo The photo
     */
    public void setPhoto(List<Photo> photo) {
        this.photo = photo;
    }

}

public class Photo {

    @SerializedName("id")
    @Expose
    private String id;
    @SerializedName("owner")
    @Expose
    private String owner;
    @SerializedName("secret")
    @Expose
    private String secret;
    @SerializedName("server")
    @Expose
    private String server;
    @SerializedName("farm")
    @Expose
    private int farm;
    @SerializedName("title")
    @Expose
    private String title;
    @SerializedName("ispublic")
    @Expose
    private int ispublic;
    @SerializedName("isfriend")
    @Expose
    private int isfriend;
    @SerializedName("isfamily")
    @Expose
    private int isfamily;
    @SerializedName("url_m")
    @Expose
    private String urlM;
    @SerializedName("height_m")
    @Expose
    private String heightM;
    @SerializedName("width_m")
    @Expose
    private String widthM;

    public Photo(){

    }

    /**
     * @return The id
     */
    public String getId() {
        return id;
    }

    /**
     * @param id The id
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * @return The owner
     */
    public String getOwner() {
        return owner;
    }

    /**
     * @param owner The owner
     */
    public void setOwner(String owner) {
        this.owner = owner;
    }

    /**
     * @return The secret
     */
    public String getSecret() {
        return secret;
    }

    /**
     * @param secret The secret
     */
    public void setSecret(String secret) {
        this.secret = secret;
    }

    /**
     * @return The server
     */
    public String getServer() {
        return server;
    }

    /**
     * @param server The server
     */
    public void setServer(String server) {
        this.server = server;
    }

    /**
     * @return The farm
     */
    public int getFarm() {
        return farm;
    }

    /**
     * @param farm The farm
     */
    public void setFarm(int farm) {
        this.farm = farm;
    }

    /**
     * @return The title
     */
    public String getTitle() {
        return title;
    }

    /**
     * @param title The title
     */
    public void setTitle(String title) {
        this.title = title;
    }

    /**
     * @return The ispublic
     */
    public int getIspublic() {
        return ispublic;
    }

    /**
     * @param ispublic The ispublic
     */
    public void setIspublic(int ispublic) {
        this.ispublic = ispublic;
    }

    /**
     * @return The isfriend
     */
    public int getIsfriend() {
        return isfriend;
    }

    /**
     * @param isfriend The isfriend
     */
    public void setIsfriend(int isfriend) {
        this.isfriend = isfriend;
    }

    /**
     * @return The isfamily
     */
    public int getIsfamily() {
        return isfamily;
    }

    /**
     * @param isfamily The isfamily
     */
    public void setIsfamily(int isfamily) {
        this.isfamily = isfamily;
    }

    /**
     * @return The urlM
     */
    public String getUrlM() {
        return urlM;
    }

    /**
     * @param urlM The url_m
     */
    public void setUrlM(String urlM) {
        this.urlM = urlM;
    }

    /**
     * @return The heightM
     */
    public String getHeightM() {
        return heightM;
    }

    /**
     * @param heightM The height_m
     */
    public void setHeightM(String heightM) {
        this.heightM = heightM;
    }

    /**
     * @return The widthM
     */
    public String getWidthM() {
        return widthM;
    }

    /**
     * @param widthM The width_m
     */
    public void setWidthM(String widthM) {
        this.widthM = widthM;
    }

    }

}

JSON Response:

{
  photos: {
  page: 1,
  pages: 3683,
  perpage: 100,
  total: "368270",
  photo: [
       {
       id: "29264707352",
       owner: "84316756@N02",
       secret: "9ed355a86e",
       server: "8603",
       farm: 9,
       title: "Tercer Patio de los Claustros de la Compañía/ Arequipa",
       ispublic: 1,
       isfriend: 0,
       isfamily: 0,
       url_m:          "https://farm9.staticflickr.com/8603/29264707352_9ed355a86e.jpg",
       height_m: "500",
       width_m: "333"
          },
        {
        id: "29339070436",
        owner: "146617764@N02",
        secret: "b52f1e9914",
        server: "8509",
        farm: 9,
        title: "2016-04-17 09.24.07",
        ispublic: 1,
        isfriend: 0,
        isfamily: 0,
        url_m: "https://farm9.staticflickr.com/8509/29339070436_b52f1e9914.jpg",
        height_m: "281",
        width_m: "500"
       },

LOGCAT

09-03 15:11:33.037 1846-1846/com.troychuinard.flickr_test E/AndroidRuntime: FATAL EXCEPTION: main
                                                                            Process: com.troychuinard.flickr_test, PID: 1846
                                                                            java.lang.NullPointerException: println needs a message
                                                                                at android.util.Log.println_native(Native Method)
                                                                                at android.util.Log.v(Log.java:118)
                                                                                at com.troychuinard.flickr_test.MainActivity$1$1.onResponse(MainActivity.java:72)
                                                                                at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
                                                                                at android.os.Handler.handleCallback(Handler.java:739)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                at android.os.Looper.loop(Looper.java:135)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
09-03 15:14:21.858 1846-1846/com.troychuinard.flickr_test I/Process: Sending signal. PID: 1846 SIG: 9

Line 72

         Log.v("RESPONSE_BODY", response.body().getTotal());

Activity

public class MainActivity extends AppCompatActivity {

private EditText mSearchTerm;
private Button mRequestButton;
private Button mSearchButton;
private String mQuery;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mSearchTerm = (EditText) findViewById(R.id.ediText_search_term);
    mRequestButton = (Button) findViewById(R.id.request_button);
    mSearchButton = (Button) findViewById(R.id.search_button_flickr);
    mRequestButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mQuery = mSearchTerm.getText().toString();
            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.flickr.com/services/rest/")
                    .client(client)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();


            ApiInterface apiInterface = retrofit.create(ApiInterface.class);
            Call<Photos> call = apiInterface.getImages(mQuery);
            call.enqueue(new Callback<Photos>() {
                @Override
                public void onResponse(Call<Photos> call, Response<Photos> response) {
                    Log.v("RESPONSE_CALLED", "ON_RESPONSE_CALLED");
                    String didItWork = String.valueOf(response.isSuccessful());
                    Log.v("SUCCESS?", didItWork);
                    Log.v("RESPONSE_CODE", String.valueOf(response.code()));
                    Photos photos = response.body();
                    Log.v("RESPONSE_BODY", "response:" + photos);
                    String total = response.body().getTotal();
                    Log.v("Total", total);
                    List<Photos.Photo> photoResults = response.body().getPhoto();
                    for (Photos.Photo photo : photoResults) {
                        Log.v("PHOTO_URL:", photo.getTitle()
                        );
                    }


                }

                @Override
                public void onFailure(Call<Photos> call, Throwable t) {

                }
            });
        }
    });

    mSearchButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent toSearch = new Intent(MainActivity.this, FlickRActivity.class);
            startActivity(toSearch);
        }
    });


}

//Synchronous vs. Asynchronous
public interface ApiInterface {

    @GET("?method=flickr.photos.search&api_key=1c448390199c03a6f2d436c40defd90e&format=json&nojsoncallback=1&extras=url_m")
    Call<Photos> getImages(@Query("text") String query);

}

}

like image 721
tccpg288 Avatar asked Sep 08 '16 01:09

tccpg288


People also ask

How do I send a body in post request in retrofit?

Request Body@POST("users/new") Call<User> createUser(@Body User user); The object will also be converted using a converter specified on the Retrofit instance. If no converter is added, only RequestBody can be used.

What is retrofit annotation?

Retrofit is a type-safe REST client for Android, Java and Kotlin developed by Square. The library provides a powerful framework for authenticating and interacting with APIs and sending network requests with OkHttp.

Is retrofit a REST API?

Retrofit is type-safe REST client for Android and Java which aims to make it easier to consume RESTful web services.


1 Answers

Based on my previous answer here your model is not correct your stat: "ok" at the end of Response is your mistake.

While you create a Photos Object you need a parent Model to keep both attribute (photos & stat)

So your model would be:

public class Model {

    Photos photos;
    int code;
    String stat;
    String message; // when you text = null


    public class Photos{
        int page;
        int pages;
        int perpage;
        int total;
        List<Photo> photo;



        public class Photo{
            String id;
            String owner;
            String secret;
            //rest of things

        }
    }
}

Also don't forget to change your Call<Photos> to Call<Model>.

like image 100
Amir Avatar answered Oct 18 '22 00:10

Amir