2017-12-22 35 views
5

マップラッパーテーブルを持つJSONデータモデルを受け取りました。私はジェネリックスを使用して、ラッパーを超えた型で渡すことを試みていますが、実行時にはうまく翻訳できません。 JSONファイルの例を次に示します。Kotlin Gson逆シリアル化

{ 
"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 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.ClassCastExceptioを取得しますn:java.lang.Object []はNetworking.PaymentMethod []にキャストできません。私は明示的な型を渡すと、期待どおりしかし、それは動作します - PAYMENTMETHODモデルに配列を解析:私はまだジェネリック型Tを使用する方法の

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

任意のアイデア?

答えて

4

データクラス:JSONへ

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

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

JSONから:

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

私は表:: class.javaを使用することができませんでした呼び出すことができます。私はTがコンパイル時には何か言うことができないコンパイラを推測しているので、しかし、それは、(最初​​の場所でのジェネリック医薬品のポイントのようなものではないのですか?)エラーがスローされます。 –

3

方法fromJsonは一般的なので、あなたがTable<T>変数のためにそれを呼び出したとき、それはArray<Any>を作成します最も適切なものとして。 PaymentMethodクラスがTに拡張されていることに気づく必要がありますが、それは可能なのかどうかわかりません。あなたがそれを作る方法を見つけた場合は、次のようなものを使用します。

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

をあなたのケースでは、私はgsonアダプタを使用しています。

:あなたは reified一般的な機能を使用することができ、予備クラスのキャストを回避するために更新

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

を:

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

それは次のようなものを書く使用するには:機能に続いて、指定されたtypeパラメータでオブジェクトを作成します

inline fun <reified T> getObjectFromString(string: String): T = 
      getGsonConverter().getAdapter(TypeToken.get(T::class.java)).fromJson(string)!! 
01使用している場合は

が容易になるだろう:

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

私は、オブジェクトがどうなるかの種類がわからない場合には、第一の溶液を使用する - 私は、そのオブジェクトに関する情報のみType変数を持っています。

2

と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

私たちはしばしばその主な目的のデータを保持することであるクラスを作成します。 では、このようなクラスのいくつかの標準的な機能および効用関数は、機械的にデータから導出しばしば あります。表はそのジェネリック型表 :: class.javaを指定する必要があるため

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 
関連する問題