Android Kotlin RxJava Retrofit - объект Json, который имеет списки в качестве атрибутов, ожидаемых BEGIN_ARRAY, но был BEGIN_OBJECT - PullRequest
0 голосов
/ 10 мая 2019

Я получаю объект Person от API, который имеет список другого объекта в качестве одного из его атрибутов. Я получаю следующую ошибку в журналах: «Expexted BEGIN_ARRAY, но был BEGIN_OBJECT по пути $». Таким образом, JSON неправильно анализирует список. Я использую Moshi для JsonParsing.

Объект Person JSON: (В реальном проекте несколько человек)

{
    "personId": 1,
    "personName": "Bert",
    "personAge": 19,
    "isFemale": "false",
    "dogs": [{
        "dogId": 1,
        "dogName": "Fred",
        "isFemale": "false"
    }, {
        "dogId": 2,
        "dogName": "Laika",
        "isFemale": "true"
    }],
    "birthDate": "2000-06-28T00:00:00"
}

Класс модели данных Dog:

data class Dog(
  @Json(name = "dogId")
  val dogId: Int,

  @Json(name = "dogName")
  val name: String,

  @Json(name = "isFemale")
  val isFemale: Boolean,
)

Класс модели данных Person:

data class Person (
  @Json(name = "personId")
  val personId: Int,

  @Json(name = "personName")
  val name: String,

  @Json(name = "personAge")
  val age: Int,

  @Json(name = "isFemale")
  val isFemale: Boolean,

  @Json(name = "dogs")
  val dogs: List<Dog>

  @Json(name = "birthDate")
  val birthDate: GregorianCalendar

)

ApiInterface: (обратите внимание на список Person, потому что он всегда возвращает список одного объекта Person)

@GET("persons/{personId}")
fun getPerson(@Path("personId") id: Int): Observable<List<Person>>

PersonRepository:

class PersonRepository @Inject constructor(val apiInterface: ApiInterface) {
  fun getPerson(personId: Int): Observable<Person>{
    return apiInterface.getPerson(personId)
      .doOnNext { value -> Log.d("PERSON_LOG_TAG", "onNext: value=$value") }
      .flatmap { response ->
         if(response.size == 1) {
            Observable.just(response[0])
         } else {
            Observable.error(Throwable("Something went wrong")
         }
      }
  } 
}

PERSON_LOG_TAG выдает «ожидаемый BEGIN_ARRAY, но ошибка BEGIN_OBJECT». Есть идеи как это исправить? Обычно это решается созданием внешнего JSON-класса, такого как PersonResponse, в котором есть список реального класса. Но я не знаю, как это сделать со списком внутри другого объекта.

1 Ответ

0 голосов
/ 10 мая 2019

Если API, созданный соглашениями, чем persons/{personId}, должен возвращать объект Person вместо списка Person.Поэтому я предполагаю, что вы должны заменить

@GET("persons/{personId}")
fun getPerson(@Path("personId") id: Int): Observable<List<Person>>

на

@GET("persons/{personId}")
fun getPerson(@Path("personId") id: Int): Observable<Person>
...