gson抛出MalformedJsonException


72

我正在使用gsonjson字符串转换为Java对象。值RESULT2是完全一样的值RESULT1。(从调试器复制;添加了反斜杠)

转换result1时会引发以下异常: com.google.gson.JsonSyntaxException:com.google.gson.stream.MalformedJsonException:预期的EOF在第1行的第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;
}

Answers:


106

我怀疑result1的末尾有些字符在调试器中看不到结束}字符。result1vs的长度是result2多少?我会注意到,result2正如您所引用的,它有169个字符。

GSON抛出特定的错误是没有空白的对象结束后,当有额外的字符,它定义空白非常狭窄(如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);

1
谢谢!我的HTTP类将json字符串下载到256字节的char缓冲区中,然后将其转换为字符串(result1)。因此,result1的长度为255而不是169。– 2012

我有同样的问题; 整个EOF东西都让我感到异常,我的问题只是纯粹和简单且格式错误的JSON。
香港

3
我遇到了同样的问题,但是我通过FileChannel获得了JSON。我很确定编码没问题。我所做的是在HDD上的文件中从字符串red上调用trim()方法,这解决了问题。

3
@ThePaul-您的字符串末尾可能还有多余的NUL(即'\ 0')字符。String.trim()不仅删除空格,还删除小于32的任何字符,而GSON将这些字符视为尾随垃圾。(然后它抱怨“我看到了右括号,因此接下来应该看到EOF,但是我看到了其他东西”)
Daniel Martin

确保您导入的是正确的json阅读器,其他库具有相同名称的类
Joe Maher 2015年

20

从我最近的经验来看,JsonReader#setLenient基本上可以使解析器非常宽容,甚至允许格式错误的JSON数据。

但是对于从受信任的RESTful API中检索到的某些数据,此错误可能是由尾随空格引起的。在这种情况下,只需trim使用数据即可避免错误:

String trimmed = result1.trim();

然后gson.fromJson(trimmed, T)可能会工作。当然,这仅涉及一种特殊情况,因此YMMV。


2
嗨@ryenus,如果我两个单词之间有空格,那该怎么办?
卡西姆2015年

5
如果字符串响应中空格很重要怎么办?在这种情况下,调整时间不好。您将丢失数据的完整性。
阿尼斯·洛尼斯

4

在调试器中,您不需要添加反斜杠,输入字段可以理解特殊字符。

在Java代码中,您需要转义特殊字符


我从调试器复制了result1的值,然后添加了反斜杠以转储result2中的特殊字符;)

前面是否可能有空格char或\ n \ r或附加到json字符串。它应该很简单
Mark Ba​​kker

result1.equals(result2)的结果是什么?
程序员布鲁斯(Bruce)

@ProgrammerBruce:result1.equals(result2)= false。两个字符串都包含相同的字符,但是result1比result2长(由我的http类引起;请参见上文)。
2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.