Java Retrofit2 Android:预期为 BEGIN_ARRAY,但在第 1 行第 2 列路径 $ 处为 BEGIN_OBJECT

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36177629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 17:32:01  来源:igfitidea点击:

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

javaandroidjsonretrofitretrofit2

提问by oxyt

I know this is not the first time someone asking about this problem but with Retrofit2 I can't find the right solution to my problem. I followed a online tutorial and it worked just fine. When I applied same code to my own endpoint i get this exception: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $I don't know how to solve this.

我知道这不是第一次有人问这个问题,但是使用 Retrofit2 我找不到正确的解决方案。我遵循了一个在线教程,它工作得很好。当我将相同的代码应用于我自己的端点时,我得到了这个异常:java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $我不知道如何解决这个问题。

Interface:

界面:

public interface MyApiService {

// Is this right place to add these headers?
@Headers({"application-id: MY-APPLICATION-ID",
        "secret-key: MY-SECRET-KEY",
        "application-type: REST"})
@GET("Music")
Call<List<Music>> getMusicList();



Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(MySettings.REST_END_POINT)
        .addConverterFactory(GsonConverterFactory.create())
        .build();
}

Client code:

客户端代码:

MyApiService service = MyApiService.retrofit.create(MyApiService.class);
Call<List<Music>> call = service.getMusicList();
call.enqueue(new Callback<List<Music>>() {

    @Override
    public void onResponse(Call<List<Music>> call, Response<List<Music>> response) {
        Log.e("MainActivity", response.body().
    }

    @Override
    public void onFailure(Call<List<Music>> call, Throwable t) {
        Log.e("MainActivity", t.toString());
    }
});

This code working with this payload:

此代码与此有效负载一起使用:

[
{
    "login": "JakeWharton",
    "id": 66577,
    "avatar_url": "https://avatars.githubusercontent.com/u/66577?v=3",
    "gravatar_id": "",
    "url": "https://api.github.com/users/JakeWharton",
    "html_url": "https://github.com/JakeWharton",
    "followers_url": "https://api.github.com/users/JakeWharton/followers",
    "following_url": "https://api.github.com/users/JakeWharton/following{/other_user}",
    "gists_url": "https://api.github.com/users/JakeWharton/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/JakeWharton/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/JakeWharton/subscriptions",
    "organizations_url": "https://api.github.com/users/JakeWharton/orgs",
    "repos_url": "https://api.github.com/users/JakeWharton/repos",
    "events_url": "https://api.github.com/users/JakeWharton/events{/privacy}",
    "received_events_url": "https://api.github.com/users/JakeWharton/received_events",
    "type": "User",
    "site_admin": false,
    "contributions": 741
},
{....

but not with this one:

但不是这个:

{
"offset": 0,
"data": [
    {
        "filename": "E743_1458662837071.mp3",
        "created": 1458662854000,
        "publicUrl": "https://api.backendless.com/dbb77803-1ab8-b994-ffd8-65470fa62b00/v1/files/music/E743_1458662837071.mp3",
        "___class": "Music",
        "description": "",
        "likeCount": 0,
        "title": "hej Susanne. ",
        "ownerId": "E743756F-E114-6892-FFE9-BCC8C072E800",
        "updated": null,
        "objectId": "DDD8CB3D-ED66-0D6F-FFA5-B14543ABC800",
        "__meta": "{\"relationRemovalIds\":{},\"selectedProperties\":[\"filename\",\"created\",\"publicUrl\",\"___class\",\"description\",\"likeCount\",\"title\",\"ownerId\",\"updated\",\"objectId\"],\"relatedObjects\":{}}"
    },
    {...

My Music class:

我的音乐课:

public class Music {

   private String ownerId;
   private String filename;
   private String title;
   private String description;
   private String publicUrl;
   private int likeCount;

   // Getters & Setters

}

采纳答案by Fred

When you say "This code is working with this payload:... but not with this one:..." that's expected and that's how it's suppose to work. In fact the error message tells you that while converting the json to a java object the call expected an array in the json but got an object instead.

当您说“此代码正在使用此有效负载:...但不适用于此有效负载:...”时,这是预期的,这就是它的工作方式。事实上,错误消息告诉您,在将 json 转换为 java 对象时,调用期望 json 中有一个数组,但却得到了一个对象。

This call:

这个电话:

@GET("Music")
Call<List<Music>> getMusicList();

expects a list of Musicobjects, that's why it works with the json:

需要一个Music对象列表,这就是它与 json 一起使用的原因:

[
  {
    "login": "JakeWharton",
    ...
  },
  ...
]

Because the json itself is an array of your Musicobjects (Retrofit can convert between json arrays to java lists). For the second json you have just an object and not an array (notice the lack of [...]). For this you need to create another call with another model that maps to that json. Let's assume you've named the model MusicList. Here's how the call could look like:

因为 json 本身是一个Music对象数组(Retrofit 可以在 json 数组之间转换为 java 列表)。对于第二个 json,您只有一个对象而不是数组(注意缺少[...])。为此,您需要使用映射到该 json 的另一个模型创建另一个调用。假设您已将模型命名为MusicList。下面是调用的样子:

@GET("Music")
Call<MusicList> getMusicList();

(Note that you might need to change the method name if you want to keep both the first call and this one).

(请注意,如果您想同时保留第一个调用和这个调用,则可能需要更改方法名称)。

The MusicListmodel can look something like this:

MusicList模型可能如下所示:

public class MusicList {
  @SerializedName("data")
  private List<Music> musics;
  // ...
}

I'm assuming that the dataarray is a list of Musicobjects, but I did notice that the jsons are completely different. You might need to adapt this as well, but I think you get the picture here.

我假设data数组是一个Music对象列表,但我确实注意到 jsons 是完全不同的。您可能也需要对此进行调整,但我认为您可以在此处了解情况。

回答by shellhub

I meet with this problem. Because playload is object instead of object array. So I remove List.

我遇到了这个问题。因为 playload 是对象而不是对象数组。所以我删除了列表。

Code Example

代码示例

UserAPI.java

用户API.java

public interface UserAPI {
    @GET("login/cellphone")
    Call<LoginResponse> login(@Query("phone") String phone, 
                              @Query("password") String password);
}

Call code

呼叫代码

Retrofit retrofit = new Retrofit
        .Builder()
        .addConverterFactory(GsonConverterFactory.create())
        .baseUrl(Constant.CLOUD_MUSIC_API_BASE_URL)
        .build();

UserAPI userAPI = retrofit.create(UserAPI.class);

userAPI.login(phone, password).enqueue(new Callback<LoginResponse>() {
    @Override
    public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
        System.out.println("onResponse");
        System.out.println(response.body().toString());
    }

    @Override
    public void onFailure(Call<LoginResponse> call, Throwable t) {
        System.out.println("onFailure");
        System.out.println(t.fillInStackTrace());
    }
});