#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}»), и это решило эту проблему. Но теперь я получаю в ответ «Неверный запрос»..