私の目標は、JSON 形式を使用してデータの任意の行を同期することです。行の正確なスキームがわからないため(これは一般的な同期方法です)、データモデルは明らかに「オブジェクト」に依存する必要があります。したがって、Java ではMap<String,Object>
、サーバーと同期する配列があります。
そのような行を JSON に変換すると、次のようになります。
{{"string":"stringvalue"},{"double1":1234.567},{"double2":1234.0},{"long":1234}}
これまでのところ、とても良いです - moshi に問題はありません - すべてが期待通りに動作します。
問題: moshi でその JSON をデシリアライズしようとすると、"long" メンバーの double-value が返されます。Moshi はすべての数値を Double に変換します。残念ながら、すべての数値を double に安全に変換できるわけではありません。非常に大きな整数 (別名 long) には、double の精度が限られているという問題があります。また、丸め効果も存在する可能性があります。
moshi でイシューをオープンしましたが、残念ながらそれはクローズされました。たぶん、私は十分に明確ではありませんでした。(第192号)
JSON には整数の概念がなく、数値と文字列のみです。しかし、上記の例の「double2」の微妙な詳細は、私の問題の解決策につながる可能性
があります。数値に小数点が含まれていない場合、それは整数であり、long に変換する必要があります。
long は無損失で double に変換できないため、値が double に変換される前にパーサーをインターセプトするメソッドが必要です。しかし、それを行う方法は?
Moshi には JsonAdapter という便利な概念がありますが、残念ながら、この場合にどのように使用できるかわかりません
。生成された double を long にキャストできないため、そのような JsonAdapter の入力タイプは Object でなければなりません。したがって、パーサーが値を変換する前に、パーサーをインターセプトする必要があります。
しかし、そこから複数の型を返す方法は? (そこから String、Double、または Long を返す必要があります。または、入力を数値のみに制限できる場合は、少なくとも Long または Double を返す必要があります。)
(私のバックエンドは PHP で書かれており、目的の出力を自動的に生成します。整数は小数点なしで書き込まれます。)