使用 Retrofit 库时出错。 Json语法异常
Having Error while working with Retrofit lib. JsonSyntaxException
我正在练习改造,我遇到了一个错误
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was NUMBER at line 1 column 31 path $.total_results
我正在使用这个apihttps://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);
}
请给我解决方案...
你创建了错误的对象
@SerializedName("total_results")
@Expose
private List<Movie> total_results;
改为
@SerializedName("total_results")
@Expose
private Int total_results;
因为根据您的错误,它应该是结果的数量并且您创建了列表,所以它只会请求 ARRAY。
如果我错了,请复制您的回复并从中获取 pojo class
http://www.jsonschema2pojo.org/
仔细查看您的 Movie.java
POJO,尤其是此字段:
@SerializedName("genre_ids")
@Expose
private List<Integer> genreIds = new ArrayList<Integer>();
...具有整数列表类型。在您提供的 JSON 中,此数组包含一个对象而不是整数 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 >();
编码愉快! ;)
我正在练习改造,我遇到了一个错误
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was NUMBER at line 1 column 31 path $.total_results
我正在使用这个apihttps://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);
}
请给我解决方案...
你创建了错误的对象
@SerializedName("total_results")
@Expose
private List<Movie> total_results;
改为
@SerializedName("total_results")
@Expose
private Int total_results;
因为根据您的错误,它应该是结果的数量并且您创建了列表,所以它只会请求 ARRAY。
如果我错了,请复制您的回复并从中获取 pojo class http://www.jsonschema2pojo.org/
仔细查看您的 Movie.java
POJO,尤其是此字段:
@SerializedName("genre_ids")
@Expose
private List<Integer> genreIds = new ArrayList<Integer>();
...具有整数列表类型。在您提供的 JSON 中,此数组包含一个对象而不是整数 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 >();
编码愉快! ;)