1. ホーム
  2. java

[解決済み] Gson が整数を浮動小数点数で表現するのを防ぐ方法

2023-07-07 17:38:01

質問

Gsonで文字列をjsonに変換しようとすると、おかしな挙動をします。以下のコードは、文字列のドラフトをjsonレスポンスに変換します。gsonがすべての整数値に'.0を追加するのを防ぐ方法はありますか?

ArrayList<Hashtable<String, Object>> responses;
Type ResponseList = new TypeToken<ArrayList<Hashtable<String, Object>>>() {}.getType();
responses = new Gson().fromJson(draft, ResponseList);

draft:
[ {"id":4077395,"field_id":242566,"body":""},
  {"id":4077398,"field_id":242569,"body":[[273019,0],[273020,1],[273021,0]]},
  {"id":4077399,"field_id":242570,"body":[[273022,0],[273023,1],[273024,0]]}
]

responses:
[ {id=4077395.0, body=, field_id=242566.0},
  {id=4077398.0, body=[[273019.0, 0.0], [273020.0, 1.0], [273021.0, 0.0]], field_id=242569.0},
  {id=4077399.0, body=[[273022.0, 0.0], [273023.0, 1.0], [273024.0, 0.0]], field_id=242570.0}
]

どのように解決するのですか?

Gsonに文字列からオブジェクトへのマップのリストを探していることを伝えていますが、これは本質的にオブジェクトの型について最善の推測をするように言っているのです。そのため JSON は整数と浮動小数点のフィールドを区別しないので Gsonは数値フィールドのデフォルトをFloat/Doubleにしなければなりません。

Gsonは基本的に、データをどのようにパースするかを決定するために、入力したいオブジェクトの型を検査するように作られています。 ヒントを与えない場合、あまりうまく動作しないでしょう。 1つの選択肢は、カスタムJsonDeserializerを定義することですが、より良い方法は、HashMapを使用せず(そして間違いなくHashtableを使用しないでください!)、代わりにGsonに期待しているデータのタイプに関するより多くの情報を与えることでしょう。

class Response {
  int id;
  int field_id;
  ArrayList<ArrayList<Integer>> body; // or whatever type is most apropriate
}

responses = new Gson()
            .fromJson(draft, new TypeToken<ArrayList<Response>>(){}.getType());

繰り返しになりますが、Gsonの全体的なポイントは、構造化されたデータを構造化されたオブジェクトにシームレスに変換することです。 オブジェクトのマップのリストのような、ほぼ未定義の構造を作成するように依頼した場合、Gson の全体的なポイントを破っていることになり、もっと単純な JSON パーサーを使用したほうがよいでしょう。