Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
179 views
in Technique[技术] by (71.8m points)

java - How I can use Gson in Retrofit library?

I used Retrofit for send request and receive the response in android but have problem when I want convert response which come from the sever it is always give me Exception:

retrofit.RetrofitError: com.google.gson.JsonSyntaxException: 
               java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING

When response from server should give me list from movies so I need put all this movies in list.

Movie (Model Class):

public class Movie {
    public Movie() {}
    @SerializedName("original_title")
    private String movieTitle;
    @SerializedName("vote_average")
    private String movieVoteAverage;
    @SerializedName("overview")
    private String movieOverview;
    ............  
}

GitMovieApi Class:

public interface GitMovieApi {
    @GET("/3/movie/{movie}")  
    public void getMovie(@Path("movie") String typeMovie,@Query("api_key") String  keyApi, Callback<Movie> response);    
}

RestAdapter configuration:

RestAdapter restAdapter = new RestAdapter.Builder()
                    .setLogLevel(RestAdapter.LogLevel.FULL)
                    .setConverter(new GsonConverter(new GsonBuilder().registerTypeAdapter(Movie.class, new UserDeserializer()).create()))
                    .setEndpoint("http://api.themoviedb.org")
                    .build(); 
                     GitMovieApi git = restAdapter.create(GitMovieApi.class);  
                git.getMovie("popular", "Keyapi", new Callback<Movie>() {
                @Override
                public void success(Movie movie, Response response) {
                    Toast.makeText(getActivity(), "s", Toast.LENGTH_LONG).show();
                }
                @Override
                public void failure(RetrofitError error) {
                    Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_LONG).show();
                }
            });

UserDeserializer:

public class UserDeserializer implements JsonDeserializer<Movie> {
        @Override
        public Movie deserialize(JsonElement jsonElement, Type typeOF,
                                 JsonDeserializationContext context)
                throws JsonParseException {
            JsonElement userJson = new JsonParser().parse("results");
            return new Gson().fromJson(userJson, Movie.class);
        }
    }    

Json(Response):

{
  "page": 1,
  "results": [
    {
      "adult": false,
      "backdrop_path": "/tbhdm8UJAb4ViCTsulYFL3lxMCd.jpg",
      "genre_ids": [
        53,
        28,
        12
      ],
      "id": 76341,
      "original_language": "en",
      "original_title": "Mad Max: Fury Road",
      "overview": "An apocalyptic story set in the furthest.",
      "release_date": "2015-05-15",
      "poster_path": "/kqjL17yufvn9OVLyXYpvtyrFfak.jpg",
      "popularity": 48.399601,
      "title": "Mad Max: Fury Road",
      "video": false,
      "vote_average": 7.6,
      "vote_count": 2114
    },
    {
      "adult": false,
      "backdrop_path": "/sLbXneTErDvS3HIjqRWQJPiZ4Ci.jpg",
      "genre_ids": [
        10751,
        16,
        12,
        35
      ],
      "id": 211672,
      "original_language": "en",
      "original_title": "Minions",
      "overview": "Minions Stuart.",
      "release_date": "2015-06-25",
      "poster_path": "/s5uMY8ooGRZOL0oe4sIvnlTsYQO.jpg",
      "popularity": 31.272707,
      "title": "Minions",
      "video": false,
      "vote_average": 6.8,
      "vote_count": 1206
    },     
],
  "total_pages": 11871,
  "total_results": 237415
}  
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You don't even need to make a custom deserializer here.

Get rid of UserDeserializer entirely, it's not needed. Your query is returning a list of movies, so make your callback to an object that actually reads the list of movies:

public class MovieList {
    @SerializedName("results")
    List<Movie> movieList;
    // you can also add page, total_pages, and total_results here if you want
}

Then your GitMovieApi class would be:

public interface GitMovieApi {
    @GET("/3/movie/{movie}")  
    public void getMovie(@Path("movie") String typeMovie,
                @Query("api_key") String keyApi,
                Callback<MovieList> response);    
}

Your RestAdapter:

RestAdapter restAdapter = new RestAdapter.Builder()
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setConverter(new GsonConverter(new GsonBuilder()).create()))
                .setEndpoint("http://api.themoviedb.org")
                .build(); 
                 GitMovieApi git = restAdapter.create(GitMovieApi.class); 

The problem is not that you have written the Deserializer incorrectly (although, you have, but it's okay because you don't need it, JsonParser is not how you do it), but the default deserialization behavior should work just fine for you. Use the above code and it will work just fine.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...