【问题标题】:java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT -ANDROID RETROFIT2java.lang.IllegalStateException:应为 BEGIN_ARRAY 但为 BEGIN_OBJECT -ANDROID RETROFIT2
【发布时间】:2018-04-24 10:35:36
【问题描述】:

我已经在 stackoverflow 中多次看到这个问题。但是这些答案并没有解决我的问题,而且我是 Retrofit 的新手。我正在为我的登录界面使用改造。我正在发送用户名,密码然后响应将是数组中的两个令牌。当我尝试登录时,log cat 显示 java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT

请求

POST : form-urlencorded

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(AllConstants.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();


  public void getUser(String username,String password){

        WebserviceAPI apiService =retrofit.create(WebserviceAPI.class);
        Call<UserResponse> call = apiService.getUsers("signin",username,password);
        call.enqueue(new Callback<UserResponse>() {
            @Override
            public void onResponse(Call<UserResponse> call, Response<UserResponse> response) {
                UserResponse result = response.body();
                Log.d("res",""+result.getData());

            }

            @Override
            public void onFailure(Call<UserResponse> call, Throwable t) {
                Log.d("res",""+t.getMessage());

            }
        });
    }

模型类

public class User {

    String id;
    String username;
    String email;
    String access_token;
    String refresh_token;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getAccess_token() {
        return access_token;
    }

    public void setAccess_token(String access_token) {
        this.access_token = access_token;
    }

    public String getRefresh_token() {
        return refresh_token;
    }

    public void setRefresh_token(String refresh_token) {
        this.refresh_token = refresh_token;
    }

}

UserResponse.java

public class UserResponse {
    List<User> data;

    public List<User> getData() {
        return data;
    }

    public void setData(List<User> data) {
        this.data = data;
    }

}

界面

public interface WebserviceAPI {
    @FormUrlEncoded
    @POST("auth")
    Call<UserResponse> getUsers(@Field("module_action") String signin ,@Field("username") String username,@Field("password") String password);
}

来自服务器端的响应:PHP

$response = ['status' => true,
            'message' => "Successfully logged in",
            'data' => [
              'access_token' => $accessToken,
              'refresh_token' => $refreshToken
            ],
          ];
            $this->returnJson($response, 200);

当我在 Postman 中运行时,响应如下所示

--------更新-----------

某些响应仅包含 statusmessage

回复例如:

{
    "status": false,
    "message": "Inactive User"
}

那我想得到message

我已编辑UserResponse 如下并尝试获取message。然后显示java.lang.NullPointerException at com.android.app.myapp.Login$3.onResponse(Login.java:92)

 public class UserResponse {
        @SerializedName("status")
        @Expose
        private String status;
    
        @SerializedName("message")
        @Expose
        private String message;
    
        User data;
    
        public String getStatus() {
            return status;
        }
    
        public void setStatus(String status) {
            this.status = status;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public User getData() {
            return data;
        }
    
        public void setData(User data) {
            this.data = data;
        }
    
    }

public void getUser(String username,String password){

        WebserviceAPI apiService =retrofit.create(WebserviceAPI.class);
        Call<UserResponse> call = apiService.getUsers("signin",username,password);
        call.enqueue(new Callback<UserResponse>() {
            @Override
            public void onResponse(Call<UserResponse> call, Response<UserResponse> response) {
                UserResponse result = response.body();
                //User data = result.getData();
                Log.d("userresponse",""+result.getMessage());
              
            }

            @Override
            public void onFailure(Call<UserResponse> call, Throwable t) {
                Log.d("res",""+t.getMessage());

            }
        });
    }

【问题讨论】:

  • 请提供堆栈跟踪或错误日志
  • 在您的 JSON 中,“数据”不是一个列表,而是一个对象。所以尝试删除 list 数据并使用 User 数据。

标签: android retrofit retrofit2


【解决方案1】:

在您的 Postman 响应中,数据字段以 JSON 对象的形式出现,而不是 JSON 数组。如果是这种情况,并且您在 UserResponse 模型中使用“数据”字段作为列表,它将无法映射它。这是我认为的问题。要解决它,您可以使用以下 UserResponse 数据模型:

public class UserResponse {
    User data;

    public User getData() {
        return data;
    }

    public void setData(User data) {
        this.data = data;
    }

}

【讨论】:

  • 我可以使用User data = result.getData(); 获取数据对象。那么如何获取message
  • 向 UserResponse 添加一个名为 message 的字符串变量,并添加它的 getter 和 setter
  • 一些没有数据的响应,那些响应只包含状态和消息。我已将消息添加到 UserResponse 然后我尝试了 result.getMessage()。但它显示 java.lang.NullPointerException。我更新了我的问题。
  • 你能粘贴你在这种情况下得到的响应以及你得到的错误的堆栈跟踪
【解决方案2】:

错误说明了一切Expected BEGIN_ARRAY but was BEGIN_OBJECT -ANDROID RETROFIT2 ,即接收到的响应或 JSON 是您尝试将其作为数组访问的对象。

将您的服务器代码更改为

$response[] = array('status' => true,
            'message' => "Successfully logged in",
            'data' => [
              'access_token' => $accessToken,
              'refresh_token' => $refreshToken
            ],
          );

echo json_encode($response);

预期的反应是

[{"status":true,"message":"Successfully logged in","data":{"access_token":null,"refresh_token":null}}]

什么是数组

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    • 1970-01-01
    • 2020-11-15
    • 2016-04-27
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多