有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在翻新库中使用Gson?

我在安卓中使用了发送请求和接收响应的改型,但当我想要转换来自服务器的响应时出现问题,它总是给我Exception

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

当来自服务器的响应应该给我电影列表,所以我需要把所有这些电影在列表中

Movie(模型类):

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<Movie> 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<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();
                }
            });

用户反序列化程序:

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(响应):

{
  "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
}  

共 (2) 个答案

  1. # 1 楼答案

    你甚至不需要在这里定制反序列化程序

    完全摆脱UserDeserializer,这是不需要的。您的查询将返回电影列表,因此请回调实际读取电影列表的对象:

    public class MovieList {
        @SerializedName("results")
        List<Movie> 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<MovieList> 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而不是你怎么做的),但是默认的反序列化行为应该对你来说很好。使用上面的代码,它会工作得很好

  2. # 2 楼答案

    在改装2中,它更简单。您的GitMovieApi类:

    interface MoviesApi {
        @GET("/3/movie/{movie}")
        Call<MovieList> getMovies(@Path("movie") String typeMovie,
                                  @Query("api_key") String keyApi);
    }
    

    然后,您只需创建一个改装对象并进行回调:

    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) {}
    });