RetroFit:java.lang.IllegalStateException:预期 BEGIN_OBJECT 但在 MVVM kotlin 应用程序中是 BEGIN_ARRAY

RetroFit: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY in MVVM kotlin app

我正在开发一个应用程序,它使用 Retrofit 进行一些网络调用,然后加载到 Room 的本地数据库中。

我的问题来了,当我尝试实现提供我在应用程序中所做的所有预订的服务流程时,我抛出了上面的标题错误:

关于 json 我想恢复的是:

{
  "reservations": [
    {
      "id": "6204d5e99b251509d20d3e57",
      "garageSpotNumber": "91",
      "area": null,
      "employee": {
        "username": "luismanuel.lucas@vass.es",
        "preferredName": "Luis Manuel Lucas Amate"
      },
      "detail": [
        {
          "id": "6204d5e99b251509d20d3e58",
          "date": 1644451200000
        }
      ],
      "dateFrom": 1644451200000,
      "dateTo": 1644451200000
    },
    {
      "id": "6204e0ad9b251509d20d3e59",
      "garageSpotNumber": "41",
      "area": null,
      "employee": {
        "username": "luismanuel.lucas@vass.es",
        "preferredName": "Luis Manuel Lucas Amate"
      },
      "detail": [
        {
          "id": "6204e0ad9b251509d20d3e5a",
          "date": 1644537600000
        }
      ],
      "dateFrom": 1644537600000,
      "dateTo": 1644537600000
    },
    {
      "id": "6204e16c9b251509d20d3e5b",
      "garageSpotNumber": "43",
      "area": null,
      "employee": {
        "username": "luismanuel.lucas@vass.es",
        "preferredName": "Luis Manuel Lucas Amate"
      },
      "detail": [
        {
          "id": "6204e16c9b251509d20d3e5c",
          "date": 1644796800000
        }
      ],
      "dateFrom": 1644796800000,
      "dateTo": 1644796800000
    },
    {
      "id": "6204e9dc9b251509d20d3e61",
      "garageSpotNumber": "60",
      "area": null,
      "employee": {
        "username": "luismanuel.lucas@vass.es",
        "preferredName": "Luis Manuel Lucas Amate"
      },
      "detail": [
        {
          "id": "6204e9dc9b251509d20d3e62",
          "date": 1644883200000
        }
      ],
      "dateFrom": 1644883200000,
      "dateTo": 1644883200000
    },
    {
      "id": "6204e89b9b251509d20d3e5d",
      "garageSpotNumber": "47",
      "area": null,
      "employee": {
        "username": "luismanuel.lucas@vass.es",
        "preferredName": "Luis Manuel Lucas Amate"
      },
      "detail": [
        {
          "id": "6204e89b9b251509d20d3e5e",
          "date": 1645056000000
        }
      ],
      "dateFrom": 1645056000000,
      "dateTo": 1645056000000
    },
    {
      "id": "6204e9929b251509d20d3e5f",
      "garageSpotNumber": "102",
      "area": null,
      "employee": {
        "username": "luismanuel.lucas@vass.es",
        "preferredName": "Luis Manuel Lucas Amate"
      },
      "detail": [
        {
          "id": "6204e9929b251509d20d3e60",
          "date": 1645142400000
        }
      ],
      "dateFrom": 1645142400000,
      "dateTo": 1645142400000
    },
    {
      "id": "620519299b251509d20d3e63",
      "garageSpotNumber": "65",
      "area": null,
      "employee": {
        "username": "luismanuel.lucas@vass.es",
        "preferredName": "Luis Manuel Lucas Amate"
      },
      "detail": [
        {
          "id": "620519299b251509d20d3e64",
          "date": 1645401600000
        }
      ],
      "dateFrom": 1645401600000,
      "dateTo": 1645401600000
    },
    {
      "id": "6205231a9b251509d20d3e65",
      "garageSpotNumber": "88",
      "area": null,
      "employee": {
        "username": "luismanuel.lucas@vass.es",
        "preferredName": "Luis Manuel Lucas Amate"
      },
      "detail": [
        {
          "id": "6205231a9b251509d20d3e66",
          "date": 1645660800000
        }
      ],
      "dateFrom": 1645660800000,
      "dateTo": 1645660800000
    }
  ]
}

所以我的模型和响应是这样的:

data class QueryGarageResponse(
    @SerializedName("reservations") var reservations: List<GarageBooking> = emptyList(),
    @SerializedName("error") var error: ErrorCall? = null
):Serializable


data class GarageBooking (
    @SerializedName("id") var id: String,
    @SerializedName("garageSpotNumber") var seatNumber : String,
    @SerializedName("area") var area:SeatArea,
    @SerializedName("employee") var employee: ReservedEmployee,
    @SerializedName("detail") var detail: BookingDetail,
    @SerializedName("dateFrom") var dateFrom: Long,
    @SerializedName("dateTo") var dateTo: Long
    ):Serializable

关于我的 api 服务:

 @GET("api/v1/garageReservation")
    fun getAllGarageReservations(
        @Header("tokenGraph")token:String,
        @Query("startdate")startDate:Long,
        @Query("finishDate")finishDate:Long,
        @Query("employee")employee:String
    ):Call<QueryGarageResponse>

我的存储库:

SeatRepository.kt

fun getAllGarageReservations(
        token:String,
        startDate: Long,
        finishDate:Long,
        employee:String
    ): LiveData<QueryGarageResponse>{
        var responseData = MutableLiveData<QueryGarageResponse>()

        api.getAllGarageReservations(token, startDate, finishDate, employee)
            .enqueue(object: Callback<QueryGarageResponse> {
                override fun onResponse(
                    call: Call<QueryGarageResponse>,
                    response: Response<QueryGarageResponse>
                ) {
                    Log.d("garage", "resp getAllGarageReservation repository: $response")
                    if(response.isSuccessful){
                        Log.d("garage", "resp repository: ${response.body()}")
                        responseData.value = response.body()
                    }else{
                        try {
                            val apiError = getErrorApi(response.errorBody()!!, ApiError::class.java)

                            apiError.error.let {
                                responseData.value =
                                    QueryGarageResponse(
                                        reservations = ArrayList(),
                                        error = ErrorCall(
                                            status = it.status,
                                            payload = it.payload.seat
                                        )
                                    )
                            }


                        } catch (ex: Exception) {
                            responseData.value =
                                QueryGarageResponse(
                                    reservations = ArrayList(),
                                    error = ErrorCall(
                                       message = ex.message!!
                                    )
                                )
                        }
                    }

                }

                override fun onFailure(call: Call<QueryGarageResponse>, t: Throwable) {
                    responseData.value =
                        QueryGarageResponse(
                           reservations = arrayListOf(),
                           error = ErrorCall(message = t.message!!)
                        )
                    }
            })
        return responseData
    }

我的视图模型

CheckGarageViewModel.kt

class CheckGarageViewModel(
    private val repository : SeatsRepository
    ): ViewModel() {

    fun getGarageBookings(): LiveData<QueryGarageResponse>{
        //1296000000 = millisegundos equivalentes a 15 dias.
        return repository.getAllGarageReservations(token = UserPreferences.prefs.token!!, System.currentTimeMillis(), System.currentTimeMillis() + 1296000000, UserPreferences.prefs.email!!)
    }

}

我不知道为什么当我真的期望数组而不是 object 时会发生此错误。

所以如果你能帮忙提前谢谢!

您遇到错误,因为您正在解析错误的数据类型。

data class GarageBooking (
    @SerializedName("id") var id: String,
    @SerializedName("garageSpotNumber") var seatNumber : String,
    @SerializedName("area") var area:SeatArea,
    @SerializedName("employee") var employee: ReservedEmployee,
    @SerializedName("detail") var detail: BookingDetail,
    @SerializedName("dateFrom") var dateFrom: Long,
    @SerializedName("dateTo") var dateTo: Long
):Serializable

根据此模型 class,detail 变量在 API 响应中应为 Object。但是请查看您添加的 API 回复。

{
  "id": "6204e89b9b251509d20d3e5d",
  "garageSpotNumber": "47",
  "area": null,
  "employee": {
    "username": "luismanuel.lucas@vass.es",
    "preferredName": "Luis Manuel Lucas Amate"
  },
  "detail": [
    {
      "id": "6204e89b9b251509d20d3e5e",
      "date": 1645056000000
    }
  ],
  "dateFrom": 1645056000000,
  "dateTo": 1645056000000
}

detail 变量是 Array 类型。因此,您需要将 detail 变量定义为模型中的列表 class,如下所示,

    @SerializedName("detail") var detail: List<BookingDetail>?,

进行此更改后,您的应用将 运行 没有错误。