Web APIなどのJSONをスマートにパースするProcessingライブラリJacksonP5を作った

はじめに

何年か前にこちらで書いた記事が元ネタになってます。 この時はパッケージングして公開まではしていなかったですが、 最近ProcessingのGradle製ライブラリテンプレートの 手入れをしたので、せっかくだからライブラリにしてみました。

JacksonP5について

JacksonのProcessingラッパーです。 JacksonはJavaでJSONを扱うためのライブラリです。 JSONのオブジェクトに対応するクラスを定義することで、 インスタンスをJSON文字列にシリアライズしたり、 JSON文字列をインスタンスにデシリアライズすることができます。

Processingにはもともと JSONObjectという JSONを扱うクラスが存在しています。 しかし、JSONObjectは学習コストが低い反面、 JSONのプロパティにアクセスする手段は getString()getFloat()などしか用意されていません。 なので、コーディングとJSONスキーマの確認作業を交互におこないがちになってしまいます。

ですがJacksonは、JSONのオブジェクトに対応するクラスを定義することで、 JSON文字列をパースしてインスタンス化することができます。 これによりJSONとJavaインスタンスを、よりスムーズに行き来することができます。

こちらがJacksonP5を使って、 ProcessingのJSONObjectをJavaインスタンスに変換するサンプルになります。

Copy
import org.enkatsu.jacksonp5.*;
import com.fasterxml.jackson.annotation.JsonProperty;
JacksonP5 jacksonp5;
Ball ball;
void setup() {
size(600, 600);
JSONObject json = new JSONObject();
json.setFloat("x", 100.0);
json.setFloat("y", 200.0);
json.setFloat("r", 50.0);
jacksonp5 = new JacksonP5(this);
ball = jacksonp5.readValue(json, Ball.class);
}
void draw() {
background(100);
ball.draw();
}
static class Ball extends JacksonP5Object {
@JsonProperty("x")
float x;
@JsonProperty("y")
float y;
@JsonProperty("r")
float r;
void draw() {
app.noStroke();
app.fill(100, 200, 250);
app.ellipse(x, y, r * 2, r * 2);
}
}

もちろんJSON文字列からもインスタンス化できます。

Copy
import org.enkatsu.jacksonp5.*;
import com.fasterxml.jackson.annotation.JsonProperty;
JacksonP5 jacksonp5;
Ball ball;
String json = """
{
"x": 100.0,
"y": 200.0,
"r": 50.0
}
""";
void setup() {
size(600, 600);
jacksonp5 = new JacksonP5(this);
ball = jacksonp5.readValue(json, Ball.class);
}
void draw() {
background(100);
ball.draw();
}
static class Ball extends JacksonP5Object {
@JsonProperty("x")
float x;
@JsonProperty("y")
float y;
@JsonProperty("r")
float r;
void draw() {
app.noStroke();
app.fill(100, 200, 250);
app.ellipse(x, y, r * 2, r * 2);
}
}

使い方は慣れれば簡単です。 まず JSONに対応するstaticクラスを定義 します。 サンプルではBallクラスですね。 このクラスは JacksonP5Objectを継承 する必要があります。 また @JsonProperty()でJSONオブジェクトが持つプロパティとクラスのプロパティを紐付ける 必要があります。 @JsonProperty()はJacksonで定義されているアノテーションです。

念の為箇条書きで列挙しておきます。

  • JSONに対応するstaticクラスを定義する
  • JacksonP5Objectを継承する
  • @JsonProperty()でプロパティを紐付ける

余談

このクラスはstatcクラスである必要があります。 これはpdeファイルで定義されたクラスは暗黙的にPAppletを継承したメインクラスの内部クラスになるためです。 まだ試していませんが、Processing IDEでも.javaファイルとしてクラスを定義すればstaticクラスにする必要はないと思います。

より実践的な使い方

では実用的な使い方について書いていこうと思います。

OpenWeatherWeather APIを使った例を示そうと思います。

OpenWeatherはアカウントを作成してAPIキーを取得する必要があるので、 こちらの 記事を参考に取得してください。


JSONをスマートにパースするProcessingライブラリJacksonP5を作った

By Katsuya Endoh, 2024-07-05