なぜこれをやろうと思ったか
サーバから受け取った、JSONをStringエンコードして、オブジェクトにカカッと変換したい。
しかも、非Null許容で、Realmには保存しないで、そのまま使いたい。
保存する場合は、Realmの便利関数があるので、そっちを使うが、保存をしない条件だとこちらで頑張る必要がある。
Moshiを使うことも想定されるが、
1.jsonパーサーを二つも入れたくない
2.Realmと相性が良いのはやっぱGson
と言うのもあって、Gsonで踏ん張ることに。
人によってはnullを許容するなどするが、筆者が非null許容派の過激派組織に所属しているため、nullは許容できない。
(非Null許容派とNull許容派の論争は別でw)
具体的にどんなケースよ?
以下のRealmオブジェクト、SampleObjがあったとする。
SampleObj.kt
//非Null許容のオブジェクトサンプル
open class SampleObj: RealmObject() {
@PrimaryKey
var sm_id : Int = 0
var name = ""
}
受け取るJSONは
{"sm_id":0,"name":"andy"}
や
{"sm_id":0,"name":null}
を想定する。
API側はnull出さないと書いてあっても、受け取る内容を書き換えられるなどの、可能性も考慮するとアプリ側で正確に受け取る必要がある。
そのままGsonで受け取ると、nullを参照した時点でアプリが落ちるのでこれをどうにかしたい。
どうしたか
以下のExtensionを作成した。
sample.kt
#StringがまともなJSONだったら、クラスの情報とDesilializerを与えるとオブジェクトにして返してくれる拡張
fun <T> String.jsonTo(type: Class<T>, typeAdapter: Any): T {
val builder = GsonBuilder().registerTypeAdapter(type,typeAdapter).serializeNulls().generateNonExecutableJson().create()
return builder.fromJson(this,type)
}
fun <T> String.jsonTo(type: Class<T>): T {
val builder = GsonBuilder().serializeNulls().generateNonExecutableJson().create()
return builder.fromJson(this,type)
}
内容の説明
簡単に言うと、GsonBuilderにserializeNullsがあるから、それ使おうぜ!って話です。
Gson側でうまく処理してくれているとは思うのですが、若干不安。。。
マサカリ、募集中です!w
お待ちしています!