简体   繁体   English

如何在Retrofit库中使用Gson?

[英]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发送请求并在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: 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
}  

You don't even need to make a custom deserializer here. 你甚至不需要在这里制作自定义反序列化器。

Get rid of UserDeserializer entirely, it's not needed. 完全摆脱UserDeserializer ,不需要它。 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: 那么你的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 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. 问题在于你没有错误地编写Deserializer (虽然你有,但它没关系,因为你不需要它, JsonParser 不是你怎么做的),但是默认的反序列化行为对你来说应该没问题。 Use the above code and it will work just fine. 使用上面的代码,它会工作得很好。

In Retrofit 2 it is even simpler. 在Retrofit 2中它甚至更简单。 Your GitMovieApi class: 你的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) {}
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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