Джексон - Невозможно десериализовать экземпляр `java.util.ArrayList` из токена START_OBJECT - PullRequest
2 голосов
/ 13 мая 2019

Я пытаюсь получить некоторые данные со спины с помощью HTTP-запроса и отображаю их как MutableList моей модели.

Код точно такой же в 2 ситуациях, но одна из них неработает, а у меня ошибка впервые?Я искал его в Google, но все примеры кода действительно отличаются от шахт, и поэтому решения.

Это ошибка, которую я получил:

D/OkHttp: Callback failure for call to http://10.0.2.2:5000/...
D/OkHttp: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList` out of START_OBJECT token
D/OkHttp:  at [Source: (String)"{"recurrenceId":1,"meetingId":4,"weekDay":21}"; line: 1, column: 1]
D/OkHttp:     at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343)
D/OkHttp:     at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1139)
D/OkHttp:     at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1093)
D/OkHttp:     at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.handleNonArray(CollectionDeserializer.java:332)
D/OkHttp:     at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:265)
D/OkHttp:     at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
D/OkHttp:     at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:27)
D/OkHttp:     at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
        at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3023)
D/OkHttp:     at fr.intech.neith.api.RecurrenceApi.toDo(RecurrenceApi.kt:34)
        at fr.intech.neith.helpers.ApiHelper$GET$1.onResponse(ApiHelper.kt:35)
D/OkHttp:     at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
D/OkHttp:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
D/OkHttp:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)

Этомой класс данных:

package fr.intech.neith.models

data class Recurrence(val recurrenceId: Int = 0,
                      val meetingId: Int = 0,
                      val weekDay: Array<Int> = arrayOf())

И это мой API, который делает запрос GET:

    package fr.intech.neith.api

import...

class RecurrenceApi(context: Context): IOnApiResponse {
    var itodo: IToDoRecurrenceList? = null
    override fun toDo(body: String) {
        val mapper = ObjectMapper()

        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        //val reader: ObjectReader = mapper.reader().forType(Meeting.class);
        val reader = mapper.readValue<MutableList<Recurrence>>(body)
        itodo!!.toExecuteR(reader)
    }

    var client = OkHttpClient()
    var api = ApiHelper(client, context)
    var url: String = "http://10.0.2.2:5000" + "/api/recurrence" // 192.168.43.135 4G - 10.0.2.2 ÉMULATEUR

    fun getRecurrenceList(meetingId: Int, cb: IToDoRecurrenceList) {
        val url2: String = url + "/${meetingId}";
        itodo = cb
        api.GET(url2, this)
    }
}

Что-то здесь не так?

Вот рабочийНапример, полностью похож на первый, потому что он работает так же:

package fr.intech.neith.models
import java.io.Serializable
import java.util.*

data class Meeting(val hostFirstName: String = "",
                   val hostLastName: String = "",
                   val estimatedTime: String = "",
                   val startDate: Date = Date(),
                   val meetingId: Int = 0,
                   val name: String = "",
                   val hasEnded: Boolean = false,
                   val hostId: Int = 0,
                   val recurrence: Array<Int> = arrayOf(),
                   val index: Int = 0,
                   val isRecurrent: Boolean = false): Serializable

package fr.intech.neith.api


import android.content.Context
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import fr.intech.neith.IOnApiResponse
import fr.intech.neith.IToDoList
import fr.intech.neith.helpers.*
import fr.intech.neith.models.Meeting
import okhttp3.OkHttpClient

class MeetingApi(context: Context): IOnApiResponse {
    var itodo: IToDoList<Meeting>? = null
    override fun toDo(body: String) {
        val mapper = ObjectMapper()

        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        val reader = mapper.readValue<MutableList<Meeting>>(body)
        itodo!!.toExecute(reader)
    }

    var client = OkHttpClient()
    var api = ApiHelper(client, context)
    var url: String = "http://10.0.2.2:5000" + "/api/meeting" // 192.168.43.135 4G - 10.0.2.2 ÉMULATEUR

    fun getMeetingList(userId: Int, cb: IToDoList<Meeting>) {
        val url2: String = url + "/${userId}/names"
        itodo = cb
        api.GET(url2, this)
    }
}

Спасибо за ваши ответы.

РЕДАКТИРОВАТЬ: Это решило проблему: mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)

1 Ответ

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

С https://craftsmen.nl/kotlin-create-rest-services-using-jersey-and-jackson/:

Чтобы десериализовать классы данных Kotlin, мы должны зарегистрировать KotlinModule Джексона на экземпляре ObjectMapper.

https://github.com/FasterXML/jackson-module-kotlin

Модуль, который добавляет поддержку сериализации / десериализации классов Kotlin и классов данных.Ранее должен существовать конструктор по умолчанию для объекта Kotlin, чтобы Джексон десериализовался в объект.С этим модулем можно автоматически использовать одиночные классы конструктора, а также классы с вторичными конструкторами или статическими фабриками.

...