Retrofit2 java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

huangapple go评论72阅读模式
英文:

Retrofit2 java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

问题

我知道这不是第一次有人询问这个问题,但是使用Retrofit2时,我无法找到解决我的问题的正确方法。我正在尝试通过我的API获取电影列表,但应用程序抛出以下错误:

预期是BEGIN_ARRAY,但在第1行第2列处是BEGIN_OBJECT,路径为 $

方法:

private void getPopularData() {
    Retrofit retrofit = RetrofitClient.getRetrofitInstance();
    MovieApi api = retrofit.create(MovieApi.class);
    Call<List<Video>> call = api.getPopularMovies(Config.API_KEY);
    call.enqueue(new Callback<List<Video>>() {
        @Override
        public void onResponse(Call<List<Video>> call, retrofit2.Response<List<Video>> response) {
            if (response.code() == 200) {
                for (int i = 0; i < response.body().size(); i++) {
                    Video video = response.body().get(i);
                    CommonModels models = new CommonModels();
                    models.setImageUrl(video.getThumbnailUrl());
                    models.setTitle(video.getTitle());
                    models.setQuality(video.getVideoQuality());
                    models.setReleaseDate(video.getRelease());
                    models.setImdb_rating(video.getImdb_rating());

                    models.setId(video.getVideosId());
                    list.add(models);
                }

                mAdapter.notifyDataSetChanged();
            }
        }

        @Override
        public void onFailure(Call<List<Video>> call, Throwable t) {
            Log.e("ERROR", " " + t);
        }
    });
}

接口:

public interface MovieApi {
    
    @GET("mostpopularmovies")
    Call<List<Video>> getPopularMovies(@Query("API-KEY") String apiKey);
}

这是我在Web浏览器上尝试时加载的响应正文:

{
  "mostpopularmovies": [
    {
      "title": "Cyborgs Amongst Us",
      "release": "2017-06-27",
      "total_view": "103"
    },
    {
      "title": "Bad Nun: Deadly Vows",
      "release": "2020-08-18",
      "total_view": "81"
    },
    {
      "title": "Greyhound",
      "release": "2020-07-10",
      "total_view": "58"
    },
    {
      "title": "The Boys",
      "release": "2019-07-25",
      "total_view": "56"
    },
    {
      "title": "Emily in Paris",
      "release": "2020-10-02",
      "total_view": "25"
    },
    {
      "title": "Enola Holmes",
      "release": "2020-09-23",
      "total_view": "15"
    },
    {
      "title": "The Owners",
      "release": "2020-08-27",
      "total_view": "5"
    }
  ]
}

任何帮助都将不胜感激

编辑:

我的Video类:

public class Video {

    @SerializedName("videos_id")
    @Expose
    private String videosId;
    @SerializedName("title")
    @Expose
    private String title;
    @SerializedName("description")
    @Expose
    private String description;
    @SerializedName("slug")
    @Expose
    private String slug;
    @SerializedName("release")
    @Expose
    private String release;
    @SerializedName("is_tvseries")
    @Expose
    private String isTvseries;
    @SerializedName("is_paid")
    @Expose
    private String isPaid;
    @SerializedName("runtime")
    @Expose
    private String runtime;
    @SerializedName("video_quality")
    @Expose
    private String videoQuality;
    @SerializedName("thumbnail_url")
    @Expose
    private String thumbnailUrl;
    @SerializedName("poster_url")
    @Expose
    private String posterUrl;
    @SerializedName("imdb_rating")
    @Expose
    private String imdb_rating;

    // 省略了getter和setter方法
}
英文:

I know this is not the first time someone asked about this problem but with Retrofit2 I can't find the right solution to my problem. I'm trying to get list if movies through my API but app throws this error:

Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

Method:

   private void getPopularData() {
        Retrofit retrofit = RetrofitClient.getRetrofitInstance();
        MovieApi api = retrofit.create(MovieApi.class);
        Call&lt;List&lt;Video&gt;&gt; call = api.getPopularMovies(Config.API_KEY);
        call.enqueue(new Callback&lt;List&lt;Video&gt;&gt;() {
            @Override
            public void onResponse(Call&lt;List&lt;Video&gt;&gt; call, retrofit2.Response&lt;List&lt;Video&gt;&gt; response) {
                if (response.code() == 200){
                    for (int i = 0; i &lt; response.body().size(); i++){
                        Video video = response.body().get(i);
                        CommonModels models =new CommonModels();
                        models.setImageUrl(video.getThumbnailUrl());
                        models.setTitle(video.getTitle());
                        models.setQuality(video.getVideoQuality());
                        models.setReleaseDate(video.getRelease());
                        models.setImdb_rating(video.getImdb_rating());

                        models.setId(video.getVideosId());
                        list.add(models);
                    }

                    mAdapter.notifyDataSetChanged();
                }
            }

            @Override
            public void onFailure(Call&lt;List&lt;Video&gt;&gt; call, Throwable t) {
                Log.e(&quot;ERROR&quot;, &quot; &quot;+t);
              
            }
        });

    }

Interface:

public interface MovieApi {
    
    @GET(&quot;mostpopularmovies&quot;)
    Call&lt;List&lt;Video&gt;&gt; getPopularMovies(@Query(&quot;API-KEY&quot;) String apiKey);
}

This is the response body which loads when I try on the web browser:

{&quot;mostpopularmovies&quot;:[{&quot;title&quot;:&quot;Cyborgs Amongst Us&quot;,&quot;release&quot;:&quot;2017-06-27&quot;,&quot;total_view&quot;:&quot;103&quot;},{&quot;title&quot;:&quot;Bad Nun: Deadly Vows&quot;,&quot;release&quot;:&quot;2020-08-18&quot;,&quot;total_view&quot;:&quot;81&quot;},{&quot;title&quot;:&quot;Greyhound&quot;,&quot;release&quot;:&quot;2020-07-10&quot;,&quot;total_view&quot;:&quot;58&quot;},{&quot;title&quot;:&quot;The Boys&quot;,&quot;release&quot;:&quot;2019-07-25&quot;,&quot;total_view&quot;:&quot;56&quot;},{&quot;title&quot;:&quot;Emily in Paris&quot;,&quot;release&quot;:&quot;2020-10-02&quot;,&quot;total_view&quot;:&quot;25&quot;},{&quot;title&quot;:&quot;Enola Holmes&quot;,&quot;release&quot;:&quot;2020-09-23&quot;,&quot;total_view&quot;:&quot;15&quot;},{&quot;title&quot;:&quot;The Owners&quot;,&quot;release&quot;:&quot;2020-08-27&quot;,&quot;total_view&quot;:&quot;5&quot;}]}

Any help is appreciated

Edit:

My Video Class:

public class Video {

    @SerializedName(&quot;videos_id&quot;)
    @Expose
    private String videosId;
    @SerializedName(&quot;title&quot;)
    @Expose
    private String title;
    @SerializedName(&quot;description&quot;)
    @Expose
    private String description;
    @SerializedName(&quot;slug&quot;)
    @Expose
    private String slug;
    @SerializedName(&quot;release&quot;)
    @Expose
    private String release;
    @SerializedName(&quot;is_tvseries&quot;)
    @Expose
    private String isTvseries;
    @SerializedName(&quot;is_paid&quot;)
    @Expose
    private String isPaid;
    @SerializedName(&quot;runtime&quot;)
    @Expose
    private String runtime;
    @SerializedName(&quot;video_quality&quot;)
    @Expose
    private String videoQuality;
    @SerializedName(&quot;thumbnail_url&quot;)
    @Expose
    private String thumbnailUrl;
    @SerializedName(&quot;poster_url&quot;)
    @Expose
    private String posterUrl;
    @SerializedName(&quot;imdb_rating&quot;)
    @Expose
    private String imdb_rating;

    public String getVideosId() {
        return videosId;
    }

    public void setVideosId(String videosId) {
        this.videosId = videosId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getSlug() {
        return slug;
    }

    public void setSlug(String slug) {
        this.slug = slug;
    }

    public String getRelease() {
        return release;
    }

    public void setRelease(String release) {
        this.release = release;
    }

    public String getIsTvseries() {
        return isTvseries;
    }

    public void setIsTvseries(String isTvseries) {
        this.isTvseries = isTvseries;
    }

    public String getIsPaid() {
        return isPaid;
    }

    public void setIsPaid(String isPaid) {
        this.isPaid = isPaid;
    }

    public String getRuntime() {
        return runtime;
    }

    public void setRuntime(String runtime) {
        this.runtime = runtime;
    }

    public String getVideoQuality() {
        return videoQuality;
    }

    public void setVideoQuality(String videoQuality) {
        this.videoQuality = videoQuality;
    }

    public String getThumbnailUrl() {
        return thumbnailUrl;
    }

    public void setThumbnailUrl(String thumbnailUrl) {
        this.thumbnailUrl = thumbnailUrl;
    }

    public String getPosterUrl() {
        return posterUrl;
    }

    public void setPosterUrl(String posterUrl) {
        this.posterUrl = posterUrl;
    }

    public String getImdb_rating() {
        return imdb_rating;
    }

    public void setImdb_rating(String imdb_rating) {
        this.imdb_rating = imdb_rating;
    }

}

答案1

得分: 1

你可以创建另一个模型类,如下所示:

class MovieListResponse {
    public List<Movie> mostpopularmovies;
}

public interface MovieApi {

    @GET("mostpopularmovies")
    Call<MovieListResponse> getPopularMovies(@Query("API-KEY") String apiKey);
}
英文:

You can make another model class like,

class MovieListResponse {
    public List&lt;Movie&gt; mostpopularmovies;
}

public interface MovieApi {

    @GET(&quot;mostpopularmovies&quot;)
    Call&lt;MovieListResponse&gt; getPopularMovies(@Query(&quot;API-KEY&quot;) String apiKey);
}

答案2

得分: 0

根据您分享的回复,您正在获取一个视频列表的数组。因此,在访问列表之前,您需要首先获取该数组。

public class MostPopularMovies{
    @SerializedName("mostpopularmovies")
    @Expose
    private List<Video> mostpopularmovies = null;

    public List<Video> getMostpopularmovies() {
        return mostpopularmovies;
    }

    public void setMostpopularmovies(List<Video> mostpopularmovies) {
        this.mostpopularmovies = mostpopularmovies;
    }
}

此外,您需要根据以下方式修改您的代码:

public interface MovieApi {
    @GET("mostpopularmovies")
    Call<MostPopularMovies> getPopularMovies(@Query("API-KEY") String apiKey);
}

您需要根据此内容更新 getPopularData 代码。

英文:

As per your shared response, You are getting a list of videos in an array. So you need to get that first before accessing the list.

public class MostPopularMovies{

@SerializedName(&quot;mostpopularmovies&quot;)
@Expose
private List&lt;Video&gt; mostpopularmovies = null;

public List&lt;Video&gt; getMostpopularmovies() {
    return mostpopularmovies;
}

public void setMostpopularmovies(List&lt;Video&gt; mostpopularmovies) {
    this.mostpopularmovies = mostpopularmovies;
}

}

Also you need to modify your code as below

public interface MovieApi {

@GET(&quot;mostpopularmovies&quot;)
Call&lt;MostPopularMovies&gt; getPopularMovies(@Query(&quot;API-KEY&quot;) String apiKey);
}

You will need to update getPopularData code as per this.

huangapple
  • 本文由 发表于 2020年10月23日 03:47:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/64489515.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定