java.lang.IllegalStateException: ожидаемый BEGIN_ARRAY, но был строкой в строке 1 столбец 1 путь $ ошибка

#android #kotlin #post #request #retrofit2

#Android #kotlin #Публикация #запрос #retrofit2

Вопрос:

Я знаю, что есть несколько других тем по этой проблеме, но я не смог найти решение для моей ошибки, поэтому, если у вас есть какие-либо предложения, пожалуйста, дайте мне знать. Я пытаюсь создать POST-запрос с параметром в теле, чтобы получить некоторые данные из API.

Мой интерфейс DataApi:

 interface ChartsDataApi {

@POST(NetworkUtils.CASH_COLLECTION_URL)
fun getCashCollection(@Body guid: String) : Call<List<CashCollection>>

@POST(NetworkUtils.TICKETS_DETAILS_URL)
fun getTicketsDetails() : Call<List<TicketDetails>>
  

}

Мое развлечение, когда я использую Retrofit и где я пытаюсь получить ответ:

 private fun geCashCollectionDetails(){
    var params : MutableMap<String, String> = HashMap()
    val BASE_URL = " here i wrote the base URL "
    val gson = GsonBuilder()
            .setLenient()
            .create()
   val api = Retrofit.Builder()
           .baseUrl(BASE_URL)
           .addConverterFactory(GsonConverterFactory.create(gson))
           .build()
           .create(ChartsDataApi::class.java)

    GlobalScope.launch(Dispatchers.IO){
        val response = api.getCashCollection(" **here i wrote the guid** ").awaitResponse()
        if(response.isSuccessful){
            val day = response.body()!!.lastIndex
            Log.d("RAZZ", day.toString())
            withContext(Dispatchers.Main){
            }
        }
    }
  

Мой класс данных для сбора наличных:

 data class CashCollection(
    @SerializedName("label")
    val label: String?,
    @SerializedName("value")
    val value: String?)
  

Ответ от server:
{«data»:[{«label»:»12.10.2020″,»value»:»0,00″},{«label»:»16.10.2020″,»value»:»0,00″},{«label»:»17.10.2020″,»value»:»0,00″},{«label»:»18.10.2020″,»value»:»0,00″}],»currency»:»EUR»}

 Process: com.eschbachit.citylinemobile, PID: 32529
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226)
    at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
    at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
    at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243)
    at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:153)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:776)
 Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
    at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:215)
    at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37) 
    at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25) 
    at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243) 
    at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:153) 
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174) 
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
    at java.lang.Thread.run(Thread.java:776 

Когда я пытаюсь протестировать и проверить данные, которые я получаю, я получаю эту ошибку.

Ответ №1:

Пожалуйста, укажите свои классы данных и ответ от сервера. Эта ошибка означает, что данные с сервера не могут быть сопоставлены с классами данных, которые вы предоставляете в результате этих запросов.

Хорошо, класс данных должен точно отражать структуру ответа. Ваш CashCollection класс должен быть

 data class CashCollection(
    val data: ArrayList<CashCollectionItem>,
    val currency: String
) {
   data class CashCollectionItem(
       @SerializedName("label")
       val label: String?,
       @SerializedName("value")
       val value: String?)
}
  

и тип ответа Call<CashCollection>

Комментарии:

1. Пожалуйста, проверьте вопрос еще раз, я добавил класс данных и ответ. Спасибо!

2. Я все еще получаю ту же ошибку, даже если я изменил этот класс..

3. Можете ли вы поделиться полным кодом проекта. Например, в GitHub

4. Проект очень сложный, и я думаю, что это не поможет вам, если вы увидите полный код

5. Может быть, проблема в том, как я пытаюсь отправить параметр тела? @Maxim

Ответ №2:

Похоже, вы неправильно сопоставили свой ответ api с классами kotlin. В вашем модифицированном api вы говорите, что ожидаете, что api вернет список CashCollections ( [{"label":"12.12.1212", "value": ""0,00}] ), но сервер возвращает объект json, где этот массив находится в свойстве data: {"data":[{"label":"12.12.1212", "value": "0,00"}]}

Вы должны обновить свой модифицированный интерфейс, чтобы соответствовать тому, что возвращает api:

 class CashCollectionResponse(
  @SerializedName("data") data: List<CashCollection>
)

interface ChartsDataApi {
  @POST("GetTheData")
  fun getCashCollection(@Body guid: String): Call<CashCollectionResponse>
}
  

Комментарии:

1. Я добавил @SerializedName («данные») в свой класс данных, но я все еще получаю ту же ошибку..

2. В какой класс данных вы добавили @SerializedName("data") ? Поскольку вы должны создать совершенно новый класс данных, который переносит данные, вы не должны добавлять его в класс данных CashCollection .

3. Кроме того, возможно, проблема не в ответе, а в запросе, как вы указали. Я советую вам прочитать это: futurestud.io/tutorials /. … Так что либо определите тело как RequestBody, либо используйте scalars converterfactory

4. Я добавил эту строку в интерфейс ChartsDataApi @Headers(«{Content-Type: text / plain; charset= UTF-8}»), и это решило эту проблему. Но теперь я получаю в ответ «Неверный запрос»..