LoginSignup
24
29

More than 5 years have passed since last update.

Kotlinにも対応したJSONライブラリーMoshiの基本的な使い方

Posted at

検証環境

この記事の内容は、以下の環境で検証しました。

  • Intellij IDEA ULTIMATE 2017.3
  • Kotlin 1.2
  • Java 1.8
  • Moshi 1.5.0
  • Gradle Projectで作成

目標

Moshiの利用方法を理解する。

具体的には以下を理解する。
* JSONをパースして、データクラスのオブジェクトを生成
* データクラスからJSONの生成

Moshiとは

Moshiとは、JavaやAndroid向けのモダンなJSONライブラリーです。
また、JSONからJavaのオブジェクトへの変換が簡単に行なえます。

準備

Moshiを使用するため、Gradleに以下の1行を追記します。

    compile 'com.squareup.moshi:moshi-kotlin:1.5.0'

事前準備

本記事とは直接関係ないですが、サンプルで使用しているクラスを事前に説明しておきます。

Userデータクラス

JSONからオブジェクトやオブジェクトからJSONにパースする際に使用するクラスです。

data class User(val name:String,val detail:UserDetail)

UserDeatailデータクラス

Userクラスのプロパティとして保持するクラスです。

data class UserDetail(val age:Int, val job:String)

createUser関数

Userデータクラスで、サンプルデータを保持したオブジェクトを生成する関数です。

fun  createUser():User{
    return User("山田太郎",UserDetail(25,"会社員"));
}

createMultiUser関数

Userデータクラスのオブジェクトを格納したList型のオブジェクトを生成する関数です。

fun createMultiUser(): List<User> {

    return listOf<User>(User("福沢諭吉",UserDetail(66,"偉人")),
            User("樋口一葉",UserDetail(24,"作家")),
            User("野口英世",UserDetail(51,"医師")))
}

実装例

クラス→JSON変換

コード例

オブジェクトをJSONに変換するコードは、以下のとおりです。

    val user = createUser()

    // クラス→JSON変換
    val moshi = Moshi.Builder().build()
    val adapter = moshi.adapter(User::class.java)
    val decodeJson = adapter.toJson(user)

    println("クラス→JSON:${decodeJson}")

解説

Moshiを使用するには、Moshiのオブジェクトが必要です。そのオブジェクトを生成するには、MoshiのBuilderクラスを使用し、builderメソッドを呼び出します。

 val moshi = Moshi.Builder().build()

adapterメソッドで、変換するクラス情報をMoshiに渡します。
戻り値として、JsonAdapter型のオブジェクトが帰ってきます。

    val adapter = moshi.adapter(User::class.java)

JsonAdapterクラスのtoJsonメソッドでJSONを生成します。

 val decodeJson = adapter.toJson(user)

実行結果


クラス→JSON:{"detail":{"age":25,"job":"会社員"},"name":"山田太郎"}

JSON→クラス変換

コード例

JSONからオブジェクトに変換するコードは、以下のとおりです。

    // JSON→クラス変換
    val json = "{\"detail\":{\"age\":30,\"job\":\"自営業\"},\"name\":\"佐藤二朗\"}"

    val fromJson = adapter.fromJson(json)
    println("JSON→クラス:${fromJson}")

解説

パースするJSON文字列を準備しています。

val json = "{\"detail\":{\"age\":30,\"job\":\"自営業\"},\"name\":\"佐藤二朗\"}"

『クラス→JSON変換』で生成したJsonAdapterのfromJsonメソッドでパースします。

val fromJson = adapter.fromJson(json)

実行結果

実行結果は、以下の通りです。

JSON→クラス:User(name=佐藤二朗, detail=UserDetail(age=30, job=自営業))

リストに格納されたクラス→JSON

コード例

オブジェクトを格納したリストをJSONに変換するコードは、以下のとおりです。

    val type = Types.newParameterizedType(List::class.java,User::class.java)
    val listAdapter:JsonAdapter<List<User>> = moshi.adapter(type)
    val multiUserJson = listAdapter.toJson(createMultiUser())

    println("リストに格納されたクラス→JSON:${multiUserJson}")

解説

List型などのコレクション型をJSON文字列にする際、Types.newParameterizedTypeメソッドでParameterizedTypeクラスのオブジェクトを生成します。
Moshiのadapterメソッドの引数にParameterizedTypeクラスのオブジェクトを渡すことにより、List型のJsonAdapterが生成できます。

    val type = Types.newParameterizedType(List::class.java,User::class.java)
    val listAdapter:JsonAdapter<List<User>> = moshi.adapter(type)

JSON文字列の生成は、これまでのadapter同様にtoJsonメソッドを呼び出します。

    val multiUserJson = listAdapter.toJson(createMultiUser())

実行結果

実行結果は、以下の通りです。

リストに格納されたクラス→JSON:[{"detail":{"age":66,"job":"偉人"},"name":"福沢諭吉"},{"detail":{"age":24,"job":"作家"},"name":"樋口一葉"},{"detail":{"age":51,"job":"医師"},"name":"野口英世"}]

JSON→リストに格納されたクラス

コード例

JSON文字列からオブジェクトを格納したリストに変換するコードは、以下のとおりです。

    val file = File("src/main/resources/list_data.json")
    val fileContents = file.absoluteFile.bufferedReader().use { it.readText() }

    val listObject = listAdapter.fromJson(fileContents);
    println("JSON→リストに格納されたクラス:${listObject}")

解説

サンプルデータはファイルで用意したため、ファイルの読み込みを記述しています。

val file = File("src/main/resources/list_data.json")
val fileContents = file.absoluteFile.bufferedReader().use { it.readText() }

ちなみに、今回使用するJSON文字列は以下の通りです。

[
  {
    "name": "佐藤一郎",
    "detail": {
      "age": 21,
      "job": "コック"
    }
  },
  {
    "name": "山田花子",
    "detail": {
      "age": 35,
      "job": "パティシエ"
    }
  },
  {
    "name": "木村二郎",
    "detail": {
      "age": 45,
      "job": "経営者"
    }
  }
]

adapterの生成方法は、『JSON→リストに格納されたクラス』と同じです。
adapterのfromJsonを呼び出すことに、List型の値が取得できます。

val listObject = listAdapter.fromJson(fileContents);

実行結果

実行結果は、以下の通りです。

JSON→リストに格納されたクラス:[User(name=佐藤一郎, detail=UserDetail(age=21, job=コック)), User(name=山田花子, detail=UserDetail(age=35, job=パティシエ)), User(name=木村二郎, detail=UserDetail(age=45, job=経営者))]

まとめ

世の中には様々なJSONのライブラリーが存在します。多くのライブラリーは、パース処理やJSON文字列変換処理を静的メソッドで定義しており、Adapterを生成する必要がありません。使い慣れるまで時間は掛かりそうですが、様々なカスタマイズが可能です。
いつか使い倒したい。

24
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
29