使用Retrofit lib时出错。 JsonSyntaxException

时间:2017-07-20 11:34:16

标签: java android api retrofit themoviedb-api

我正在练习改造,我遇到了错误
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was NUMBER at line 1 column 31 path $.total_results

我正在使用此api https://api.themoviedb.org/3/movie/550?api_key=########################

这是我的代码

MainActivity.java

public class MainActivity extends AppCompatActivity {

private static final String Tag=MainActivity.class.getSimpleName();
private static final String APIKEY="###########################";
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    final ProgressDialog pDialog= new ProgressDialog(this);
    pDialog.setMessage("Loading...");
    pDialog.show();
    final RecyclerView recyclerView =(RecyclerView)findViewById(R.id.recyclerMovie);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));

    ApiInterface apiService= ApiClient.getClient().create(ApiInterface.class);
    Call<MovieResponse> call =apiService.getTopRatedMovie(APIKEY);

    call.enqueue(new Callback<MovieResponse>() {
        @Override
        public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) {
            List<Movie> movies=response.body().getResults();
            Log.d(Tag, "Numbers Of Movies Received"+ movies.size());
            MovieAdapter adapter =new MovieAdapter(movies,R.layout.list_item_movies,getApplicationContext());
            recyclerView.setAdapter(adapter);
            pDialog.dismiss();

        }

        @Override
        public void onFailure(Call<MovieResponse> call, Throwable t) {
            Log.d(Tag,"Error:-"+t.toString());
            pDialog.dismiss();
            Toast.makeText(getApplicationContext(),"Oops Error...",Toast.LENGTH_SHORT).show();
        }
    });
}}

Movie.java

public class Movie {

    @SerializedName("poster_path")
    @Expose
    private String posterPath;

    @SerializedName("adult")
    @Expose
    private boolean adult;

    @SerializedName("overview")
    @Expose
    private String overview;

    @SerializedName("release_date")
    @Expose
    private String releaseDate;

    @SerializedName("genre_ids")
    @Expose
    private List<Integer> genreIds = new ArrayList<Integer>();

    @SerializedName("id")
    @Expose
    private Integer id;

    @SerializedName("original_title")
    @Expose
    private String originalTitle;

    @SerializedName("original_language")
    @Expose
    private String originalLanguage;

    @SerializedName("title")
    @Expose
    private String title;

    @SerializedName("backdrop_path")
    @Expose
    private String backdropPath;

    @SerializedName("popularity")
    @Expose
    private Double popularity;

    @SerializedName("vote_count")
    @Expose
    private Integer voteCount;

    @SerializedName("video")
    @Expose
    private Boolean video;

    @SerializedName("vote_average")
    @Expose
    private Double voteAverage;


    public Movie(String posterPath, boolean adult, String overview, String releaseDate, List<Integer> genreIds, Integer id, String originalTitle, String originalLanguage, String title, String backdropPath, Double popularity, Integer voteCount, Boolean video, Double voteAverage) {
            this.posterPath = posterPath;
            this.adult = adult;
            this.overview = overview;
            this.genreIds = genreIds;
            this.backdropPath = backdropPath;
            this.id=id;
            this.originalLanguage=originalLanguage;
            this.originalTitle=originalTitle;
            this.releaseDate=releaseDate;
            this.title=title;
            this.video=video;
            this.voteAverage=voteAverage;
            this.voteCount=voteCount;
            this.popularity=popularity;
    }
    //getter and setter methods }

MovieResponse.java

public class MovieResponse {

@SerializedName("page")
@Expose
private int page;

@SerializedName("results")
@Expose
private List<Movie> results;

@SerializedName("total_pages")
@Expose
private int total_pages;

@SerializedName("total_results")
@Expose
private List<Movie> total_results;
//getter and setter methods}

ApiClient.java

public class ApiClient {

public static final String Base_URl="http://api.themoviedb.org/3/";
public static Retrofit retrofit=null;

public static Retrofit getClient(){
    if(retrofit==null){
        retrofit=new Retrofit.Builder()
                .baseUrl(Base_URl)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    return retrofit;
}}

ApiInterface.java

public interface ApiInterface{

@GET("movie/top_rated")
Call<MovieResponse> getTopRatedMovie(@Query("api_key") String apiKey);

@GET("movie/{id}")
Call<MovieResponse> getMovieDetails(@Path("id") int id, @Query("api_key") String apiKey); 

}

请给我解决方案......

2 个答案:

答案 0 :(得分:0)

你创建了错误的对象

@SerializedName("total_results")
@Expose
private List<Movie> total_results;

更改为

   @SerializedName("total_results")
   @Expose
   private Int total_results;

因为根据你的错误,它应该是结果的数量,你创建了List,所以它只会要求ARRAY。

如果我错了,请复制你的回复并参加pojo课程 http://www.jsonschema2pojo.org/

答案 1 :(得分:0)

仔细查看您的Movie.java POJO,特别是此字段:

@SerializedName("genre_ids")
@Expose
private List<Integer> genreIds = new ArrayList<Integer>();

...具有整数列表的类型。在您提供的JSON中,此数组包含Objects而不是Integer ID。您可以像这样表示这个对象:

public class Genre {
    @SerializedName("id")
    @Expose
    private int id;

    @SerializedName("name")
    @Expose
    private String name;
}

此外,此数组的实际名称为genres(不是genres_ids)。因此,为了避免解析错误,您唯一需要的是将上面的字段更改为:

@SerializedName("genres")
@Expose
private List<Genre> genres = new ArrayList< Genre >();

快乐的编码! ;)