简体   繁体   中英

How to solve JSON retrofit error with Deferred Response

I followed with tutorial : https://android.jlelse.eu/android-networking-in-2019-retrofit-with-kotlins-coroutines-aefe82c4d777

I need to recover data in JSON format, I get the following error message :

com.squareup.moshi.JsonDataException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $*

I looked at this answer but I don't know how to adapt it to my code : Retrofit Expected BEGIN_OBJECT but was BEGIN_ARRAY

This is my interface

interface LocationService {
    @GET("locations?countryid=fr")
    fun getLocationList() : Deferred<Response<LocationResponse>>
}

LocationResponse

data class LocationResponse (val results : List<Location>)

Location Model

data class Location (
    @field:Json(name = "id") val id : String,
    @field:Json(name = "category") val category : String,
    @field:Json(name = "label") val label : String,
    @field:Json(name = "value") val value : String
)

The JSON is like this

[
  {
    "id":"city_39522",
    "category":"Villes",
    "label":"Parisot (81310)",
    "value":null
 },
 {
   "id":"city_36661",
   "category":"Villes",
   "label":"Paris 9ème (75009)",
   "value":null
 },
 {
   "id":"city_39743",
   "category":"Villes",
   "label":"Parisot (82160)",
   "value":null
 }
]

I'm already getting a list, I don't see how to correct the error ?

You have to update your interface as:

interface LocationService {
    @GET("locations?countryid=fr")
    fun getLocationList() : Deferred<Response<List<Location>>>
}

Also you don't need LocationResponse class and remove the below code:

data class LocationResponse (val results : List<Location>)

You are expecting the response and parsing it like this:

{
  "results": [
    { .. }
  ]
}

But Actual response is like this:

 [
    { .. }
  ]

The error explains that you are expecting object at the root but actual json data is array, so you have to change it to array.

In your API interface you're defining getLocationList() method to return a LocationResponse object whereas the API actually returns a list of objects, so to fix this define the method as follows..

interface LocationService {
    @GET("locations?countryid=fr")
    fun getLocationList() : Deferred<Response<List<Location>>>
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM