我如何在Retrofit库中使用Gson?
我使用Retrofit发送请求并在android中接收响应但是当我想要来自服务器的转换响应时它有问题总是给我Exception
:
retrofit.RetrofitError: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING
当服务器的响应应该给我电影列表,所以我需要把所有这些电影放在列表中。
Movie
(模特class):
public class Movie { public Movie() {} @SerializedName("original_title") private String movieTitle; @SerializedName("vote_average") private String movieVoteAverage; @SerializedName("overview") private String movieOverview; ............ }
GitMovieApi
类:
public interface GitMovieApi { @GET("/3/movie/{movie}") public void getMovie(@Path("movie") String typeMovie,@Query("api_key") String keyApi, Callback response); }
RestAdapter
配置:
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() { @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 { @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(响应):
{ "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 }
你甚至不需要在这里制作自定义反序列化器。
完全摆脱UserDeserializer
,不需要它。 您的查询正在返回电影列表,因此请回拨实际读取电影列表的对象:
public class MovieList { @SerializedName("results") List movieList; // you can also add page, total_pages, and total_results here if you want }
然后你的GitMovieApi
类将是:
public interface GitMovieApi { @GET("/3/movie/{movie}") public void getMovie(@Path("movie") String typeMovie, @Query("api_key") String keyApi, Callback response); }
你的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);
问题不在于你没有错误地编写Deserializer
(虽然你有,但它没关系,因为你不需要它, JsonParser
不是你怎么做的),但是默认的反序列化行为对你来说应该没问题。 使用上面的代码,它会工作得很好。
在Retrofit 2中,它更简单。 你的GitMovieApi
课程:
interface MoviesApi { @GET("/3/movie/{movie}") Call getMovies(@Path("movie") String typeMovie, @Query("api_key") String keyApi); }
而且您只需要创建一个Retrofit对象,然后进行回调:
Retrofit retrofit = new Retrofit.Builder() .baseUrl(MOVIES_BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); service = retrofit.create(MoviesApi.class); Call mlc = service.getMovies(getArguments().getString(ARG_MOVIE_TYPE), getString(R.string.THE_MOVIE_DB_API_TOKEN)); mlc.enqueue(new Callback () { @Override public void onResponse(Call call, Response response) { movies = response.body().movieList; } @Override public void onFailure(Call call, Throwable t) {} });