【问题标题】:java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY retrofit, kotlinjava.lang.IllegalStateException: 预期 BEGIN_OBJECT 但 BEGIN_ARRAY 改造,kotlin
【发布时间】:2020-02-10 01:02:53
【问题描述】:

我正在尝试使用 Retrofit 在我的应用程序上实现用户注册,但是我一直收到此错误,不确定是什么问题,java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY

这是邮递员的回复

{
"isSuccessful": true,
"message": "successful",
"user": {
    "name": "Jackline Jazz",
    "email": "jackijazz@gmail.com",
    "phone": "000000"
}

}

我有两个模型类 User 模型类

data class User(
val name: String,
val email:String,
val phone:String

)

还有登录响应类

data class LoginResponse(
val isSuccessful:Boolean,
val message: String,
val user: List<User>

)

我的改造对象

object RetrofitClient {

private const val BASE_URL = "http://10.0.2.2:7000/"

val instance: RetrofitApi by lazy {
    val retrofit = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()

retrofit.create(RetrofitApi::class.java)
}

}

改造 api

@FormUrlEncoded
@POST("users/register")
fun userRegister(
    @Field("name") name: String,
    @Field("email") email: String,
    @Field("password") password: String,
    @Field("confirmPassword") confirmPassword: String
): Call<LoginResponse>

还有我的注册班

RetrofitClient.instance.userRegister(name, email, password, confirmPassword)
            .enqueue(object : Callback<LoginResponse> {
                override fun onFailure(call: Call<LoginResponse>, t: Throwable) {
                    Toast.makeText(applicationContext, t.message, Toast.LENGTH_LONG).show()`
                }

                override fun onResponse(call: Call<LoginResponse>, response: Response<LoginResponse>) {
                    if (response.body()?.isSuccessful!!){

                        val intent = Intent(applicationContext, MainActivity::class.java)

                        startActivity(intent)

                    }else{
                        Toast.makeText(applicationContext, response.body()?.message, Toast.LENGTH_LONG).show()
                    }
                }

            })
    }
}

如果可能的话,有人帮我实现 Kotlin 协程

【问题讨论】:

    标签: android kotlin retrofit kotlin-coroutines


    【解决方案1】:

    your previous question 中,您遇到了users/login 端点。您创建了一个 LoginResponse 来模拟来自服务器的响应。在那里,users/login 返回一个List&lt;User&gt;,所以LoginResponse 必须这样设置。

    现在,您正在访问users/register 端点...但您仍在尝试使用LoginResponse。正如您从 JSON 中看到的那样,您从只有一个用户的服务器获得 不同的 JSON。因此,您需要一个不同的响应类(例如,RegisterResponse)来模拟这个新响应:

    data class RegisterResponse(
      val isSuccessful:Boolean,
      val message: String,
      val user: User
    )
    
    @FormUrlEncoded
    @POST("users/register")
    fun userRegister(
        @Field("name") name: String,
        @Field("email") email: String,
        @Field("password") password: String,
        @Field("confirmPassword") confirmPassword: String
    ): Call<RegisterResponse>
    

    【讨论】:

    • CommonsWare,自 2009 年以来为新用户提供持续的调试帮助:D
    • @ToshGitonga:那么您的RegisterResponse 与 JSON 不匹配。请注意,您的错误消息也与 JSON 不匹配 - 错误表示它遇到了一个数组,但您的问题中显示的 JSON 不包含数组。因此,该错误指的是一些与您的问题不同的 JSON。
    【解决方案2】:

    BEGIN_ARRAY 表示返回的一些 JSON 包含一个 JSON 数组 ([]),其中您的对象架构需要一个 JSON 对象 ({})。 有时 API 会根据它们处理的客户端返回不同的响应,因此最好在代码中调试手头的问题。一种方法是临时使用 Retrofit 的标量转换器工厂。

    添加这个依赖:

    dependencies {
        implementation 'com.squareup.retrofit2:converter-scalars:<your-retrofit-version>'
    }
    

    还有这段代码

    val retrofit = new Retrofit.Builder()  
            .addConverterFactory(ScalarsConverterFactory.create())
            ...
    

    并返回 Callable&lt;String&gt; 而不是您的自定义类型,并记录从您的服务器实际返回的内容。然后你就可以采取相应的行动了。

    【讨论】:

    • 我使用了httpinterceptor,从服务器返回的内容与邮递员的响应完全相同
    • 啊,我的错,我看得太晚了:你的模型中有val user: List&lt;User&gt;,但你想要val user: User
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-26
    • 2015-07-24
    • 1970-01-01
    • 2021-01-27
    • 2016-04-27
    • 2020-02-03
    • 2014-08-01
    相关资源
    最近更新 更多