Kotlin Gson Deserializing

Я получаю модель данных JSON, которая имеет таблицу оболочек карт. Я пытаюсь использовать generics для передачи в типе, который находится за пределами оболочки, но он не хорошо переводится во время выполнения. Вот пример моего файла JSON:

{ "Table": [ { "paymentmethod_id": 1, "paymentmethod_description": "Cash", "paymentmethod_code": "Cash", "paymentmethod_is_ach_onfile": false, "paymentmethod_is_element": false, "paymentmethod_is_reward": false, "paymentmethod_is_openedgeswipe": false, "paymentmethod_update_user_id": 1, "paymentmethod_insert_user_id": 1, "paymentmethod_insertdate": "2014-10-07 14:53:16", "paymentmethod_deleted": false, "paymentmethod_is_mobile_visible": true } ] } 

Класс оболочки, который я использую, называется Table.

 data class Table<T>( @SerializedName("Table") val models : Array<T> ) 

Фактический класс модели – PaymentMethod.

 data class PaymentMethod( @SerializedName("paymentmethod_id") val idNumber : Int = -1 ) 

Я создал общий класс диспетчера данных, который принимает тип <T>. Я думаю, что использовать подклассы диспетчера данных для локализации ввода и результатов (например, объявление класса модели PaymentMethod .

 open class NXDataManager<T>(manager: NXNetworkManager? = null, rpc : String?, parameters: List<Pair<String, String>>? = null, method : String = "get") { ... open fun sendRequest(completionHandler: (models:Array<T>) -> Unit, errorHandler: (error:FuelError) -> Unit) { val request = NXNetworkRequest(rpc, parameters, method) request.send(manager, completionHandler = { s: String -> val table: Table<T> = Gson().fromJson(s) completionHandler(table.models) }, errorHandler = errorHandler) } inline fun <reified T> Gson.fromJson(json: String) = this.fromJson<T>(json, object: TypeToken<T>() {}.type) } 

Мой подклассовый менеджер данных определяет модель для анализа.

 final public class PaymentMethodsDataManager : NXDataManager<PaymentMethod> { constructor () : super("genGetPaymentMethods") } 

Когда я запускаю код как:

 val table: Table<T> = Gson().fromJson(s) 

Я получаю сообщение об ошибке java.lang.ClassCastException: java.lang.Object [] не может быть передан в Networking.PaymentMethod [] . Однако, когда я передаю явный тип, он работает так, как ожидалось, – анализ массива в моделях PaymentMethod:

 val table: Table<PaymentMethod> = Gson().fromJson(s) 

Любые идеи о том, как я могу использовать общий тип T?

Класс данных:

 data class Table<T>( @SerializedName("Table") val models : Array<T> ) 

к JSON:

 val gson = Gson() val json = gson.toJson(table) 

от JSON:

 val json = getJson() val table = gson.fromJson(json, Table::class.java) 

Метод fromJson является общим, поэтому, когда вы вызываете его для переменной Table<T> он создает Array<Any> как наиболее подходящий. Вы должны заметить, что класс PaymentMethod расширяет T generic, но я не знаю, возможно ли это. Если вы узнаете, как это сделать, используйте что-то вроде следующего:

 val table: Table<T> = Gson().fromJson<Table<PaymentMethod>>(s) 

В вашем случае я использую адаптеры gson. Следующая функция создает объект с указанным параметром type :

 fun getObjectFromString(type: Type, string: String) = Gson().getAdapter(TypeToken.get(type)).fromJson(string) 

Чтобы использовать его, напишите следующее:

 val table: Table<T> = getObjectFromString(Table<PaymentMethod>::class.java, s) as Table<PaymentMethod> 

Обновить

Чтобы избежать использования запасного класса, вы можете использовать обобщенную функцию reified :

 inline fun <reified T> getObjectFromString(string: String): T = getGsonConverter().getAdapter(TypeToken.get(T::class.java)).fromJson(string)!! 

В этом случае использование будет проще:

 val table: Table<T> = getObjectFromString<Table<PaymentMethod>>(s) 

Я использовал первое решение в тех случаях, когда я не знаю, каким будет тип объекта. У меня есть только переменная Type с информацией об этом объекте.

java.lang.ClassCastException: java.lang.Object [] не может быть передан в Networking.PaymentMethod []

Ваш JSON

 { "Table": [ { "paymentmethod_id": 1, "paymentmethod_description": "Cash", "paymentmethod_code": "Cash", "paymentmethod_is_ach_onfile": false, "paymentmethod_is_element": false, "paymentmethod_is_reward": false, "paymentmethod_is_openedgeswipe": false, "paymentmethod_update_user_id": 1, "paymentmethod_insert_user_id": 1, "paymentmethod_insertdate": "2014-10-07 14:53:16", "paymentmethod_deleted": false, "paymentmethod_is_mobile_visible": true } ] } 

Создайте data class PaymentMethod .

Мы часто создаем классы, основной целью которых является хранение данных. В таком классе некоторые стандартные функции и функции полезности часто механически выводятся из данных.

 data class PaymentMethod(@SerializedName("Table") val table:ArrayList<PaymentData> ) data class PaymentData ( @SerializedName("paymentmethod_id") val paymentmethod_id: Int, @SerializedName("paymentmethod_description") val paymentmethod_description: String, @SerializedName("paymentmethod_code") val paymentmethod_code:String, @SerializedName("paymentmethod_is_ach_onfile") val paidStatus:Boolean, @SerializedName("paymentmethod_is_element") val paymentmethod_is_element:Boolean, @SerializedName("paymentmethod_is_reward") val paymentmethod_is_reward:Boolean, @SerializedName("paymentmethod_is_openedgeswipe") val paymentmethod_is_openedgeswipe:Boolean, @SerializedName("paymentmethod_update_user_id") val paymentmethod_update_user_id:Int, @SerializedName("paymentmethod_insert_user_id") val paymentmethod_insert_user_id:Int, @SerializedName("paymentmethod_insertdate") val paymentmethod_insertdate:String, @SerializedName("paymentmethod_deleted") val paymentmethod_deleted:Boolean), @SerializedName("paymentmethod_is_mobile_visible") val paymentmethod_is_mobile_visible:Boolean ) 

Вы можете так позвонить

  val paymentDATA = Gson().fromJson<PaymentMethod>("JSON_RESPONSE", PaymentMethod::class.java) val _adapterPaymentHistory = paymentDATA.table 
Intereting Posts
Отменить возвращаемое значение для возврата Unit? Как реализовать ленивый адаптер recyclerView для загрузки, например realm recyclerView, используя kotlin Каков самый ранний уровень API Android, с которым я могу использовать Kotlin? Является ли тип неявного свойства одинаковым с явным типом свойства? Запрос на Android всегда дает исключение тайм-аута сокета Задача Firebase еще не завершена Ожидание объявления члена XML в / из Java / Kotlin, кросс-платформенный Как добавить новый источник с помощью gradle kotlin-dsl Проблема с выпуском Android 3.0 Gradle 3.0 Есть ли какой-нибудь метод в Kotlin, который позволяет мне перевести значение из диапазона в другой диапазон? Scala эквивалентный способ Range для пользовательского класса Является ли «org.jetbrains.anko: anko-commons: $ anko_version» неправильным? Вызывающая (базовая) делегированная функция при использовании делегирования класса из переопределения Возвращает результат запроса postgresql в функции