jsonデータの取得方法〜asXxxxとxxxxValueのちがい
jsonの値を取得する処理を調べながら書いてたら、asTextとtextValueが混在してて違いが気になったのでメモ。
リファレンスを読みながら、文字列・数値・ブール値を取得&出力するコードで結果を確認していく。
jacksonのバージョンは2.9。
リファレンスはこれ↓
JsonNode (jackson-databind 2.9.0 API)
以下の実験用jsonデータを読み取る
// sample.json { "string": { "name": "apple", "price": "200", "isStock": "true" }, "int": { "name": 100, "price": 300, "isStock": 0 }, "boolean": { "name": true, "price": true, "isStock": false }, "null": { "name": null, "price": null, "isStock": null } }
asText()
Method that will return a valid String representation of the container value, if the node is a value node (method isValueNode() returns true), otherwise empty String.
これは「値を参照する場合、コンテナ値の有効な文字列表現を返して、それ以外(=キー)を取得する時は空文字を返す」らしい。
コンテナ値ってなんだろって思ったけど、バシッとくる答え見つからなかった。
javaUtilクラスにある型っていうのかな。よくいう"普通の型"なら文字列に読み替えてくれるぽいな。
nullの時でもぬるぽにならないから、気づかずに画面にnullって表示されて初めて気づくのとか悔しいから気をつけないと。
// asText String string_name_asText = root.get("string").get("name").asText(); //"apple" System.out.println(string_name_asText); //apple String int_name_asText = root.get("int").get("name").asText(); //100 System.out.println(int_name_asText); //100 String boolean_name_asText = root.get("boolean").get("name").asText(); //true System.out.println(boolean_name_asText); //true String null_name_asText = root.get("null").get("name").asText(); //null System.out.println(null_name_asText); //null //キーを取得する時 String reading_key_asText = root.get("string").asText(); //"string": { "name": "apple", "price": "200", "isStock": "true" } System.out.println(reading_key_asText); //"" (空文字)
textValue
Method to use for accessing String values. Does NOT do any conversions for non-String value nodes; for non-String values (ones for which isTextual() returns false) null will be returned. For String values, null is never returned (but empty Strings may be)
これは文字列以外が入ってたらnullが返される。
最後の文曰く、nullじゃなくて空文字が返されることもあるのか?これは謎だ。。。
これはキーを取得するとnullが返る。
//textValue String string_name_textValue = root.get("string").get("name").textValue(); //"apple" System.out.println(string_name_textValue); //apple String int_name_textValue = root.get("int").get("name").textValue(); //100 System.out.println(int_name_textValue); //null String boolean_name_textValue = root.get("boolean").get("name").textValue(); //true System.out.println(boolean_name_textValue); //null String null_name_textValue = root.get("null").get("name").textValue(); //null System.out.println(null_name_textValue); //null //キーを取得する時 String reading_key_textValue = root.get("string").textValue(); //"string": { "name": "apple", "price": "200", "isStock": "true" } System.out.println(reading_key_textValue); //null
asInt
Method that will try to convert value of this node to a Java int. Numbers are coerced using default Java rules; booleans convert to 0 (false) and 1 (true), and Strings are parsed using default Java language integer parsing rules. If representation cannot be converted to an int (including structured types like Objects and Arrays), default value of 0 will be returned; no exceptions are thrown.
文字列の値を取得する場合、数値に変換できたらその数を、変換できない時は0を返す。
どうやらブール値は0(false)と1(true)に変換されるらしい。
//asInt int string_price_asInt = root.get("string").get("price").asInt(); //"200" System.out.println(string_price_asInt); //200 int string_name_asInt = root.get("string").get("name").asInt(); //"apple" System.out.println(string_name_asInt); //0 int int_price_asInt = root.get("int").get("price").asInt(); //100 System.out.println(int_price_asInt); //100 int boolean_price_asInt = root.get("boolean").get("price").asInt(); //true System.out.println(boolean_price_asInt); //1 int null_price_asInt = root.get("null").get("price").asInt(); //null System.out.println(null_price_asInt); //0
intValue
Returns integer value for this node, if and only if this node is numeric (isNumber() returns true). For other types returns 0. For floating-point numbers, value is truncated using default Java coercion, similar to how cast from double to int operates.
これは数値でない場合は0を返す。bool値も変換してくれない。
double型の時は、intにキャストする時と同じように切り捨てて返す。
//intValue int string_price_intValue = root.get("string").get("price").intValue(); //"200" System.out.println(string_price_intValue); //0 int int_price_intValue = root.get("int").get("price").intValue(); //300 System.out.println(int_price_intValue); //300 int boolean_price_intValue = root.get("boolean").get("price").intValue(); //true System.out.println(boolean_price_intValue); //0 int null_price_intValue = root.get("null").get("price").intValue(); //null System.out.println(null_price_intValue); //0
asBoolean
Method that will try to convert value of this node to a Java boolean. JSON booleans map naturally; integer numbers other than 0 map to true, and 0 maps to false and Strings 'true' and 'false' map to corresponding values. If representation cannot be converted to a boolean value (including structured types like Objects and Arrays), default value of false will be returned; no exceptions are thrown.
これもasStringやasIntと同じように、trueまたはfalseに変換できるなら型が違くても変換してくれる。
asBooleanでは、
文字列の場合、"true"or"false"なら自動変換でそれ以外の文字列はfalse、数値なら0はfalse、整数はtrueへ自動変換してくれる。
//asBoolean boolean string_isStock_asBoolean = root.get("string").get("isStock").asBoolean(); //"true" System.out.println(string_isStock_asBoolean); //true boolean int_isStock_asBoolean = root.get("int").get("isStock").asBoolean(); //0 System.out.println(int_isStock_asBoolean); //false boolean int_price_asBoolean = root.get("int").get("price").asBoolean(); //300 System.out.println(int_price_asBoolean); //true boolean boolean_isStock_asBoolean = root.get("boolean").get("isStock").asBoolean(); //false System.out.println(boolean_isStock_asBoolean); //false boolean null_isStock_asBoolean = root.get("null").get("isStock").asBoolean(); //null System.out.println(null_isStock_asBoolean); //false
booleanValue
Method to use for accessing JSON boolean values (value literals 'true' and 'false'). For other types, always returns false.
ここまできたら予想通りだが、boolean型以外の値はfalseを返す。
//booleanValue boolean string_isStock_booleanValue = root.get("string").get("isStock").booleanValue(); //"true" System.out.println(string_isStock_booleanValue); //false boolean int_isStock_booleanValue = root.get("int").get("isStock").booleanValue(); //0 System.out.println(int_isStock_booleanValue); //false boolean boolean_isStock_booleanValue = root.get("boolean").get("isStock").booleanValue(); //false System.out.println(boolean_isStock_booleanValue); //false boolean null_isStock_booleanValue = root.get("null").get("isStock").booleanValue(); //null System.out.println(null_isStock_booleanValue); //false
おまけ asXxxx(defaultValue)
asXxxx()をオーバーロードするメソッドもある。
これは値がnullの時に、引数に指定したdefaultValueが返る。
これ使えばnullチェックしなくて済むから便利、、、
ちょっとだけ例
//asText(defalutValue) String string_name_asText_defalut = root.get("string").get("name").asText("secret!"); //"apple" System.out.println(string_name_asText_defalut); //apple String null_name_asText_defalut = root.get("null").get("name").asText("secret!"); //null System.out.println(null_name_asText_defalut); //secret!
おわりに
シンプルだけどひとつずつ調べると、使い勝手が良くなるようによーく考えてAPI作ってくれてるんだな〜って思った。