[Kotlin] Jackson とかを使ってJSONと仲良くする

[Kotlin] Jackson とかを使ってJSONと仲良くする

こんばんは、七色メガネです。

今回は Java の JSONパーサー・ライブラリ である Jackson を Kotlin で利用する方法についてまとめて見たいと思います。

Jackson で出来ること

Jackson は、JSON を扱うための Java ライブラリです。
Jackson を使用することで、主に次のことが実現できるようになります。

  • Java オブジェクトをJSONに変換する
  • JSONを Java オブジェクトに変換する

Jackson はJava用のライブラリですが、それと同等の機能をもつkotlin用のライブラリとして Jackson Kotlin Module が開発されています。

したがって、JavaでJacksonを使ってできることは、Kotlinでも実現することができます。

前準備

環境情報

  • IDE: IntelliJ
  • language: Kotlin1.3.21
  • Build: Gradle
  • Jackson-kotlin-module: 2.9.0

build.gradle への追記情報

今回はgradleを使用するので、 build.gradle で jackson を関連づけます、

Jackson を使ってみる

Kotlin オブジェクトを JSON に変換する

ではまず、KotlinオブジェクトをJSONに変換して見ましょう。

用意したデータクラスは次の通りです。

Human.kt

今回はプログラム内部で予めデータを用意しておきます。
用意するデータは2種類で、単一のHumanインスタンスと、Humanインスタンスのリストです。

generate data


ではこれらのデータに対してパースを実行しましょう。

jacksonを使用したパースは非常に簡単で、次の2ステップで実行できます。

  1. jackObjectMapper インスタンスを生成する。
  2. Mapperインスタンスの writeValueAsString メソッドにオブジェクトを渡して実行する。

上記の処理を行なっているのが次のソースになります。単一オブジェクトへのパースとリストへのパースの2パターンを用意しました。

parserController.kt

今回はSpringBootでRestAPI的に作っています。
任意のリクエストの生成・実行ができる Postman というツールで上記のエンドポイントにリクエストを投げて見た結果がこちらです。

いずれのパターンでも、プログラム内部で定義したクラスインスタンスを正常にJSONに変換できていることが確認できます。

JSON を Kotlin オブジェクトに変換する

では次は逆に、JSONをオブジェクトに変換して見ましょう。

JSONをプログラム内で定義しても良いのですが、エスケープの関係で可視性が落ちるので今回はPUTを受け取るハンドラを用意し、Postman からJSONをリクエストボディとして渡す方向で実装したいと思います。

今回のパース方法も簡単で、処理は2ステップです。

  1. jackObjectMapper インスタンスを生成する。
  2. Mapperインスタンスの readValue メソッド で変換先のクラスの型情報を定義し、JSONデータを渡して実行する。

例によって用意するパターンは、データが単一のものと複数のものの2つを受け取るものの2つです。配列構造に対してパースをかけるときは、 readValue における型宣言で、リスト型のクラス型を宣言しましょう。

parserController.kt


では先ほどと同じようにPostmanから実行して見ましょう。
今回はJSONをリクエストボディで指定して実行します。

レスポンスの型をクラスにしてreturnすると勝手にJSONになってしまうようなので、コンソールへの出力も確認して見ます。

レスポンスを返す前にプログラム内で println してみたものです。JSONをクラスに変換できていることが分かりますね。

最後は、JSONが配列構造を持っている場合です。

番外編1:Spring の @JsonProperty でJSONのパースを行う。

今回は Jackson でパースを行いましたが、SpringBoot を使用している場合、JSONデータを @JsonProperty をもつデータクラスへと自動で紐づけることができます。

JSONの紐付け先として次のようなデータクラスを用意します。このとき @JsonProperty のvalue に設定した値とJSONの各項目名が等しければ、Springの自動紐付けが働きます。

HumanResource.kt

このデータクラスを @RequestBody アノテーションでの定義クラスとして指定してやれば、リクエストボディとして渡されたJSONデータが自動的にこのデータクラスに紐づけられます。

Jackson が使用できない場合は、こちらでも十分対応できるでしょう。

parserController.kt

番外編2: Spring で @JsonProperty を使用しないでJSONのパースを行う。

余談でもう一つ。

先ほどは HumanResource というデータクラスを作成し、このデータクラスのプロパティとJSONの各項目名とを明示的に紐付けて自動パースを行いました。

このやり方の場合、Kotlin側に既に存在するデータクラスとJSONを紐づけるとき、その名称が違っていたとしても、データクラス側の@JsonProperty内Value値を指定することででその差異を吸収して紐付けることができます。

ですがもし、データクラスの項目名とJSONの各項目名が完全に一致しているとしたら改めてデータクラスを用意する必要はありません。その条件さえ満たしていれば、@JsonProperty を使用していないデータクラスでもJSONからの自動パースが働くのです。

Human.kt

json_data

parserController.kt

リクエストボディの受け取りと同時にパースが完了してしまっているので、かなり簡潔に記述することができましたね。

まとめ

  • Jackson Kotlin Module を使用することで、JSON > Kotlinオブジェクトへのパース、またその逆のパースを実現できる。
  • SpringBoot を使用しているならば、@JsonProperty を使用することで、または場合によっては使用しなくても、パース処理を行うことができる。

 

Kotlinカテゴリの最新記事