web-dev-qa-db-ja.com

gsonはMalformedJsonExceptionをスローします

gsonを使用してjson文字列をJava-Objectに変換しています。 result2の値はresult1の値とまったく同じです。 (デバッガーからコピー、バックスラッシュを追加)

Result1の変換中に次の例外がスローされます:com.google.gson.JsonSyntaxException:com.google.gson.stream.MalformedJsonException:Expected EOF at line 1 column 170

result2の変換は正常に機能します。

Json文字列はjsonlint.comによると有効です。

public static Userinfo getUserinfo()
{
    String result1 = http.POST("https://www.bitstamp.net/api/balance/",
                                postdata, true);
    String result2 = "{\"btc_reserved\": \"0\", \"fee\": \"0.5000\", \"btc_available\": \"0.10000000\", \"usd_reserved\": \"0\", \"btc_balance\": \"0.10000000\", \"usd_balance\": \"30.00\", \"usd_available\": \"30.00\"}";
    Gson gson = new Gson();
    Userinfo userinfo1 = gson.fromJson(result1, Userinfo.class); //throws Exception
    Userinfo userinfo2 = gson.fromJson(result2, Userinfo.class); //works fine

    return userinfo1;
}
private class Userinfo {

    public Userinfo(){
    }

    public float usd_balance;
    public float btc_balance ;
    public float usd_reserved;
    public float btc_reserved;
    public float usd_available;
    public float btc_available;
    public float fee;
    public float last_update;
}
65
Non

Result1の最後には、終了}文字に続くデバッガーで見ることができない文字があると思われます。 result1result2の長さは? result2は、引用したとおり169文字です。

GSONは、空白ではないオブジェクトの末尾の後に余分な文字がある場合に特定のエラーをスローし、空白veryを(JSON仕様として)定義しますしません)-\t\n\r、およびスペースとしてのみスペースとしてカウントされます。 特に、末尾のNUL(\0)文字は空白としてカウントされず、このエラーが発生することに注意してください

末尾の余分な文字の原因を簡単に把握して除去できない場合は、GSONに寛容なモードで解析するように指示することもできます。

Gson gson = new Gson();
JsonReader reader = new JsonReader(new StringReader(result1));
reader.setLenient(true);
Userinfo userinfo1 = gson.fromJson(reader, Userinfo.class);
96
Daniel Martin

私の最近の経験から、 JsonReader#setLenient は基本的にパーサーを非常に寛容にし、不正なJSONデータを許可します。

ただし、信頼できるRESTful APIから取得した特定のデータでは、このエラーは末尾の空白が原因である可能性があります。このような場合、単にtrimデータがエラーを回避します:

String trimmed = result1.trim();

その後、gson.fromJson(trimmed, T)は期待どおりに動作するはずです。

17
ryenus

デバッガでは、バックスラッシュを追加する必要はありません。入力フィールドは特殊文字を理解します。

Javaコードでは、特殊文字をエスケープする必要があります

4
Mark Bakker