どうも、最近、OneRepublic の「Counting Star」という曲にハマっているボクです。
そうなんですよね~、JSONって入れ子構造になっていることが多くて、これ、どうやってNULLチェックしたら良いんだと。
そんなこんなで、今回は、入れ子構造の場合のJSONのNULLチェックにトライ。
Kubernetesのコンテナは絶賛調査中です...つまり解決に至っていません...。
まずは、JavaでJSONを利用できるようにライブラリの導入を検討
Javaの標準ライブラリ(API)には用意されていないらしいので、外部からインストールするしかないらしい 。
と思ったのですが、
⇧ 上記サイト様によりますと、
Java6からJavaScriptを扱うことができるようになり、RhinoというJavaScriptエンジンを使用していました。
Java8からは新たにNashornというJavaScriptエンジンが追加され、Rhinoから置き換えることができます。
【Java】JSONデータを標準API、Jackson、JSON in Javaで扱う方法 | 侍エンジニア塾ブログ | プログラミング入門者向け学習情報サイト
JavaでJavaScriptを扱うためには、まずScriptEngineManagerクラスを使ってインスタンスを生成します。
そのオブジェクトからgetEngineByNameメソッドを呼び出し、引数にエンジンnashornを指定します。
そして、evalメソッドを使って、JavaScriptを実行します。
【Java】JSONデータを標準API、Jackson、JSON in Javaで扱う方法 | 侍エンジニア塾ブログ | プログラミング入門者向け学習情報サイト
⇧ Java側で、JavaScriptを扱うことによって、JSONを実現する方法もあるようです。Node.jsなんかみたいに、サーバーサイドでJavaScriptを実装するイメージですかね?
まぁ、今回は、ライブラリを導入してみたいと思いますが、Javaで扱えるJSONライブラリとして、有名どころとしては、
ライブラリ名 | パッケージ名 |
---|---|
Jackson | com.fasterxml.jackson |
Gson | com.google.code.gson |
JSON in Java | org.json |
が、あるみたいです。
その他にも、JSONを扱うライブラリとしては、
⇧ 上記の公式サイトが詳しいです。
とりあえず、JSON in Java
とりあえず、生の人っていう居酒屋のノリと言うわけじゃないけど、一番機能の少なそうなJSON in Javaを試してみます。
Jacksonは、多機能すぎて、調べるのが大変そうということで、時間のありそうなときにチャレンジしたいということで。
http://json.org/ にアクセスして、
下の方にスクロールすると、「JSON-java」ってあるので、クリック。
Git Hubのページに遷移するので、一番したのほうにスクロールすると、
https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav のリンクがあるので、クリック。
リポジトリに遷移するので、
今回は、「Download」の「jar」をクリック。
ブラウザの下部に表示される選択肢で、「保存」を選択。 jarをダウンロードするときのこの説明は、毎回思うけど、怖すぎる...何とかならんもんか。
保存されます。
ダウンロードされました。
JavaプロジェクトにJSON in Javaのライブラリを追加
とりあえず、Eclipseを起動して、「ファイル(F)」>「新規(N)」>「Java プロジェクト」。(ほんとなら、「パースペクティブ」を「Java EE」とかにして、「動的Webプロジェクト」とかを作成しないと、JSONデータとかも受け取れんと思われますが)
「プロジェクト名(P):」を適当に付けて、「次へ(N) >」をクリック。
「完了(F)」をクリック。
Javaプロジェクトができました。
ダウンロードしておいたライブラリを配置する用のディレクトリを作成しときます。
プロジェクトディレクトリ(ここでは、「JsonTest」)の直下に、新たにフォルダーを追加。「フォルダー名(N):」は適当に。「完了(F)」をクリック。
Eclipseに作成した「lib」ディレクトリに、ダウンロードしておいたライブラリをドラッグ&ドロップします。
「ファイルをコピー(C)」にチェックされた状態で「OK」。
そしたら、ライブラリをビルドパスに追加していきます。
⇧ 上記サイト様を参考にさせていただきました。
「パッケージ・エクスプローラー」のなかのプロジェクトを選択した状態で、右クリックし「ビルド・パス(B)」>「外部アーカイブの追加(V)...」。
先程、配置したライブラリを選択。
自分の場合ですと、「C:¥Eclipse4.6¥pleiades¥workspace05¥JsonTest¥lib¥json-20180813.jar」になります。
ご自分のライブラリを配置した場所に合わせてください。
「参照ライブラリー」が追加され、その中にライブラリが追加されていればOKのようです。
Javaで利用してみる
では、さっそく、Javaでクラスを作成して、ライブラリを使っていくということで。
まずは、クラスを作成。「新規(W)」>「クラス」をクリック。
「パッケージ(K):」「名前(M):」を適当に入力し、「public static void main(String[] args)(V)」にチェックし、「完了(F)」をクリック。
メインメソッドを持つクラスファイルが出来上がります。
今回は、外部から、
{ "id": "957c43f2-fa2e-42f9-bf75-6e3d5bb6960a", "name": "The Best Product", "brand": { "id": "9bcd817d-0141-42e6-8f04-e5aaab0980b6", "name": "Baccarat", "owner": { "id": "b21a80b1-0c09-4be3-9ebd-ea3653511c13", "name": "Fortune Legend Limited", "manager" : { "id" : "98jughul-078b-ih09-kju9-p09juhugh086", "name" : null, "employee" : { "id" : "98jughul-078b-ih09-kju9-p09lhrs54676", "name" : null } } } } }
みたいなJSON形式のデータが送られてきた体で。
本当は、AngularJSとかのJavaScriptフレームワークと、Javaプロジェクトを連携させて、JSONデータの送受信したいんですが、調べる時間が無いですね(涙)
⇧ 上記サイト様で、JSON形式のデータをエンコードしておきます。
そしたらば、クラスを編集。
How to convert JSONObject to HashMap in Java - Quora
⇧ 上記サイト様を参考、というかほぼまんま使わせていただきました。
package ts0818.json.test; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; public class JsonTest { public static void main(String[] args) { // 送られてきたと仮定したJSONデータ(エンコードしたもの) String json = "{\r\n \"id\": \"957c43f2-fa2e-42f9-bf75-6e3d5bb6960a\",\r\n \"name\": \"The Best Product\",\r\n \"brand\": {\r\n \"id\": \"9bcd817d-0141-42e6-8f04-e5aaab0980b6\",\r\n \"name\": \"Baccarat\",\r\n \"owner\": {\r\n \"id\": \"b21a80b1-0c09-4be3-9ebd-ea3653511c13\",\r\n \"name\": \"Fortune Legend Limited\",\r\n \"manager\" : {\r\n \"id\" : \"98jughul-078b-ih09-kju9-p09juhugh086\",\r\n \"name\" : null,\r\n \"employee\" : {\r\n \"id\" : \"98jughul-078b-ih09-kju9-p09lhrs54676\",\r\n \"name\" : null\r\n }\r\n }\r\n }\r\n } \r\n}"; // JSONデータをJSONオブジェクトに JSONObject jsonObject = new JSONObject(json); // JSONの順序は保証されないらしい... System.out.println(jsonObject); // JSONオブジェクトの値チェック Map<String, Object> resultMap = toMap(jsonObject); System.out.println(resultMap); } public static Map<String, Object> toMap(JSONObject object) throws JSONException { Map<String, Object> map = new HashMap<String, Object>(); Iterator<String> keysItr = object.keys(); while(keysItr.hasNext()) { String key = keysItr.next(); Object value = object.get(key); // JSONオブジェクトの値が、配列の場合、 if(value instanceof JSONArray) { value = toList((JSONArray) value); // JSONオブジェクトの値が、オブジェクトの場合 } else if(value instanceof JSONObject) { value = toMap((JSONObject) value); } // NULLが含まれてる場合は、空文字に置き換え if(value == JSONObject.NULL) { value = ""; } map.put(key, value); } return map; } public static List<Object> toList(JSONArray array) throws JSONException { List<Object> list = new ArrayList<Object>(); for(int i = 0; i < array.length(); i++) { Object value = array.get(i); if(value instanceof JSONArray) { value = toList((JSONArray) value); } else if(value instanceof JSONObject) { value = toMap((JSONObject) value); } list.add(value); } return list; } }
そしたらば、メインメソッドを持ったクラス(ここでは、「JsonTest.java」)を選択した状態で右クリックし、「実行(R)」>「3 Java アプリケーション」を選択。(このへんはEclipseのバージョンによって若干、名前とか変わってるかもです。)
コンソールに結果が表示されます。
JSONの順番は、むちゃくちゃですが、nullは、空文字に置き換わったようです。順番を保持する方法は分からずでした...。
注意する点としては、ライブラリとしてJSON in Java を利用する場合、
値がnull
のJSON
は、JSONObject.NULL
オブジェクトとして扱われます。
⇧ 上記サイト様でも仰っているように、
value == null
のような、Java本来のnull判定では、NULLかどうかを判定できないということですかね。
そして、今回のJSONデータの場合だと、JSONArrayの場合の処理は必要なかったっぽいですね...。
本当は再帰処理は、パフォーマンス的にあまり推奨されないらしいんですが、うまい方法が見つからずですね...。
そもそも、JSON in Javaライブラリだと、JSONを、Javaクラスのオブジェクトにマッピングして変換できないんじゃないか疑惑が...
⇧ 上記サイト様によりますと、Apache CommonsのライブラリのBeanUtilsを使えば、MapのデータからJavaクラスのオブジェクトを生成したりできるらしいですが、JSONデータの構成が、複数のJavaクラスのオブジェクトを集めて成り立っているとしたら、上手くマッピングできない気が...
やはり、JacksonかGsonを使っていく感じになるんですかね。
Java、勉強せねばですが、どう勉強すれば良いのか分からずですね...。
今回はこのへんで。