简体   繁体   中英

Retrofit returns null values

I am using Retrofit and I am a quite noob in Android.

My JSON response

    {
    "movie": {
        "_id": "568661682d33bca267fdf81b",
        "poster_path": "https://image.tmdb.org/t/p/w154/xHfhQIK4BNlsGv5Ylx8mVq0hJT1.jpg",
        "adult": false,
        "overview": "",
        "release_date": "2015-05-15",
        "id": 76341,
        "original_title": "Mad Max: Fury Road",
        "original_language": "en",
        "title": "Mad Max: Furia en la carretera",
        "vote_count": 3105,
        "__v": 0,
        "popular": true,
        "production_companies": [],
        "cast": [],
        "genre_ids": [
            53,
            28,
            12
        ]
    }
}

This is my Movie model:

public class Movie {

public String Id;
//more variables

public String getId() {
    return Id;
}

public void setId(String id) {
    Id = id;
}
//more getter and setter

My Retrofit interface

public interface MyApiEndPointsInterface {
  @GET("/movie/{id}")
  Call<Movie> getMovie(@Path("id") int id);
}

And the code in the activity

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    MyApiEndPointsInterface apiService =
            retrofit.create(MyApiEndPointsInterface.class);

    Call<Movie> call = apiService.getMovie(76341);

    call.enqueue(new Callback<Movie>() {
        @Override
        public void onResponse(Response<Movie> response, Retrofit retrofit) {
            Log.d("MainActivity", response.body().title);
        }

        @Override
        public void onFailure(Throwable t) {

        }
    });

I thinks it can be the JSON response because it has an superior instance, but I don't know how to work with it in the code.

I don't get an response, is it all correct?

The problem is that the JSON parser is not expecting the un-named root object that is wrapping the 'movie' data in the JSON.

If you can change the JSON that the server returns, remove the outer object so that you have just

{
    "_id": "568661682d33bca267fdf81b",
    "poster_path": "https://image.tmdb.org/t/p/w154/xHfhQIK4BNlsGv5Ylx8mVq0hJT1.jpg",
    "adult": false,
    "overview": "",
    "release_date": "2015-05-15",
    "id": 76341,
    "original_title": "Mad Max: Fury Road",
    "original_language": "en",
    "title": "Mad Max: Furia en la carretera",
    "vote_count": 3105,
    "__v": 0,
    "popular": true,
    "production_companies": [],
    "cast": [],
    "genre_ids": [
        53,
        28,
        12
    ]
}

If you can't alter the server's response, there's a few ways to handle it on the client side. I'd simply create another object to map to the outer JSON object, so leaving your existing Movie class as-is, add:

public class MovieResponse {
 public Movie movie;
}

and then change the Retrofit call to use the MovieResponse instead of the Movie. You can then refer to

movieResponse.movie

Your String names are case sensitive to how they appear in the JSON output. Change String Id to String id and it should work, it doesn't matter in the getter and setter names ( getId works for instance), but the variable itself needs to match the case in the JSON.

Change movie model to:

public class Movie { 

    @SerializedName("_id")
    public String id;
    //more variables 

    public String getId() {
        return Id;
    } 

    public void setId(String id) {
        id = id;
    }
}

Gson needs to know exactly how to map your model via reflection. It mainly uses your variable name if you dont state otherwise.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM