retrofit error Expected BEGIN_ARRAY but was BEGIN_

2019-08-26 14:27发布

问题:

I try to get Otp using mobile number, but it display error like this

E/FAILISJERE: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 54 path $.data

This is my URL := http://192.168.1.105/XXXX/XXXXX/XXXXX/default/send-otp

Request Fields: mobileNo,name

Response is like this :-

{
"error": false,
"msg": "Otp sent successfully",
"data": {
    "otp": 152265
}

}

APIClient.Kt:-

object ApiClient {

private var retrofit: Retrofit? = null
val client: Retrofit
    get() {
        if (retrofit == null) {
            retrofit = Retrofit.Builder()
                    .baseUrl(AppConfig.BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()
        }
        return retrofit!!
    }

}

APIInterface.kt:-

interface ApiInterface {
@FormUrlEncoded
@POST("send-otp")
fun GET_OTP(@Field("name") name: String, @Field("mobileNo") mobileNo: String): Call<OTPSendResponse>

}

AppConfig.kt:-

class AppConfig {
companion object {
    const val BASE_URL = "http://192.168.1.105/XXXX/XXXXX/XXXXX/default/"
}

}

OtpModel.kt:-

class OtpModel {
constructor(otp: Int) {
    this.otp = otp
}
@SerializedName("otp")
var otp: Int = 0

}

OtpSendResponse.kt:-

class OTPSendResponse {

constructor(error: String, data: ArrayList<OtpModel>, msg: String) {
    this.error = error
    this.data = data
    this.msg = msg
}
@SerializedName("error")
var error: String = ""

@SerializedName("msg")
var msg: String = ""

@SerializedName("data")
var data: ArrayList<OtpModel> = ArrayList()

}

MyActivity.kt:-

private fun sendNameAndMobileNum(name: String, mobileNum: String) {
    Log.e("MOBILE", "${mobileNum}")
    val apiService = ApiClient.client.create(ApiInterface::class.java)

    val call = apiService.GET_OTP(name, mobileNum)

    call.enqueue(object : Callback<OTPSendResponse> {

        override fun onResponse(call: Call<OTPSendResponse>, response: Response<OTPSendResponse>) {
            Log.e("OTP", "${response.body()?.data!![0].otp}")

            val otpIs = response.body()!!.data[0].otp
            val i = Intent(this@AddNumActivity, OTPVerifyActivity::class.java)
            i.putExtra("otp", otpIs)
            i.putExtra("mobileNum", mobileNum)
            startActivity(i)
        }

        override fun onFailure(call: Call<OTPSendResponse>, t: Throwable) {
            Toast.makeText(this@AddNumActivity, "Ooops !!", Toast.LENGTH_SHORT).show()

            Log.e("FAILISJERE", "${t.message}")
        }
    })
}

回答1:

Change Model class because in json response there are not any array so remove ArrayList tag

data: ArrayList<OtpModel>  

to

data: OtpModel

because it's no array



回答2:

Your error means that the conversion from what you received from the API to the class you provided in your call is not correct.

E/FAILISJERE: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 54 path $.data

Means the deserializer expected an array but has found a "{" character at the line 1 column 54 (which corresponds to the data field) instead of the '[' it was expected for the "data" field. So that means your model is not correct.

And if you look at your model, you can indeed see that the "data" object here is represented as an ArrayList, while it should be a single object.

So you can just replace in your model

data: ArrayList<OtpModel>  

by:

data: OtpModel 

and you should be good