LoginSignup
4
5

More than 5 years have passed since last update.

org.json.JSONObjectを使う際の注意点

Last updated at Posted at 2018-08-10

Androidの開発でorg.json.JSONObjectを使った際にハマったことをまとめます。

①put(String key, java.util.Map value)

下記のテストをJUnit(Java)とAndroid test(Android)で行うと結果に違いがあります。

JSONObjectTest.java
    @Test
    public void testJson() throws JSONException {
        Map<String, String> map = new HashMap<String, String>();
        map.put("key", "value");

        JSONObject json = new JSONObject();
        json.put("map", map);

        System.out.println(json.toString());
    }
JUnit
{"map":{"key":"value"}}
AndroidTest
{"map":"{key=value}"}

これはAndroidのorg.json.JSONObjectにput(String key, java.util.Map value)がないためです。
そのためAndroidではput(String key, Object value)が呼ばれます。

またパラメータvalueの制約として下記があります。

Object: a JSONObject, JSONArray, String, Boolean, Integer, Long, Double, NULL, or null. May not be NaNs or infinities

このため、AndroidでMapをputすると上記のような結果となります。

②JSONObject(java.util.Map map)

①の解決方法としてJSONObjectへの詰め替えがありますが、これにも注意が必要です。

①のテストを下記のように修正して行うと。

JSONObjectTest.java
    @Test
    public void testJson() throws JSONException {
        Map<String, String> map = new HashMap<String, String>();
        map.put("key", "value");

        JSONObject json = new JSONObject();
        // Map -> JSONObject
        // json.put("map", map);
        json.put("map", new JSONObject(map));

        System.out.println(json.toString());
    }
JUnit
{"map":{"key":"value"}}
AndroidTest
{"map":{"key":"value"}}

同じ結果になります。
ただし、MapのvalueをStringからnullに変更した場合問題が起きます。

JSONObjectTest.java
    @Test
    public void testJson() throws JSONException {
        Map<String, String> map = new HashMap<String, String>();
        // String -> null
        // map.put("map", map);
        map.put("key", null);

        JSONObject json = new JSONObject();
        json.put("map", new JSONObject(map));

        System.out.println(json.toString());
    }
JUnit
{"map":{}}
AndroidTest
{"map":{"key":null}}

この違いの原因は正確にはわかりませんでしたが、おそらくリファレンスの

In particular, calling put(name, null) removes the named entry from the object but put(name, JSONObject.NULL) stores an entry whose value is JSONObject.NULL.

という仕様が関係していると思われます。

そもそも、リファレンスには

Values may be any mix of JSONObjects, JSONArrays, Strings, Booleans, Integers, Longs, Doubles or NULL. Values may not be null, NaNs, infinities, or of any type not listed here.

と書いてあるのでMap、nullあとListの扱いには注意(詰め替え)が必要です。

4
5
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
4
5