java 如何在 Retrofit 库中使用 Gson?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32490011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How I can use Gson in Retrofit library?
提问by mohammad tofi
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 发送请求并在 android 中接收响应,但是当我想要转换来自服务器的响应时遇到问题,它总是给我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):
Movie
(模型类):
public class Movie {
public Movie() {}
@SerializedName("original_title")
private String movieTitle;
@SerializedName("vote_average")
private String movieVoteAverage;
@SerializedName("overview")
private String movieOverview;
............
}
GitMovieApi
Class:
GitMovieApi
班级:
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 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):
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
}
采纳答案by durron597
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:
UserDeserializer
完全摆脱,它不需要。您的查询正在返回电影列表,因此请对实际读取电影列表的对象进行回调:
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:
那么你的GitMovieApi
班级将是:
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 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 notthat you have written the Deserializer
incorrectly (although, you have, but it's okay because you don't need it, JsonParser
is nothow you do it), but the default deserialization behavior should work just fine for you. Use the above code and it will work just fine.
问题不在于您写错了Deserializer
(虽然,您有,但没关系,因为您不需要它,JsonParser
而不是您如何做),但默认的反序列化行为应该适合您。使用上面的代码,它会工作得很好。
回答by bendaf
In Retrofit 2 it is even simpler. Your GitMovieApi
class:
在 Retrofit 2 中,它甚至更简单。你的GitMovieApi
班级:
interface MoviesApi {
@GET("/3/movie/{movie}")
Call<MovieList> getMovies(@Path("movie") String typeMovie,
@Query("api_key") String keyApi);
}
And than you just need to create a Retrofit object, and make a callback:
而不是您只需要创建一个 Retrofit 对象,并进行回调:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(MOVIES_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
service = retrofit.create(MoviesApi.class);
Call<MovieList> mlc = service.getMovies(getArguments().getString(ARG_MOVIE_TYPE), getString(R.string.THE_MOVIE_DB_API_TOKEN));
mlc.enqueue(new Callback<MovieList>() {
@Override
public void onResponse(Call<MovieList> call, Response<MovieList> response) {
movies = response.body().movieList;
}
@Override
public void onFailure(Call<MovieList> call, Throwable t) {}
});