Kotlin Gson反序列化
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin Gson反序列化相关的知识,希望对你有一定的参考价值。
我收到一个有地图包装表的JSON数据模型。我正在尝试使用泛型传递超出包装器的类型但它在运行时不能很好地转换。这是我的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
泛型,但我不知道它是否可能。如果您了解如何制作它,请使用以下内容:
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
以上是关于Kotlin Gson反序列化的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Gson @SerializedName 注释在 Kotlin 中反序列化嵌套的 Json API 响应
Kotlin中Json的序列化与反序列化 -- GsonMoshi