【问题标题】:gson throws MalformedJsonExceptiongson 抛出 MalformedJsonException
【发布时间】:2012-07-14 02:56:48
【问题描述】:

我正在使用 gsonjson 字符串转换为 Java-Object。 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;
}

【问题讨论】:

    标签: java json gson


    【解决方案1】:

    我怀疑 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);
    

    【讨论】:

    • 谢谢!我的 HTTP 类将 json 字符串下载到 256 字节的字符缓冲区中,然后将其转换为字符串(result1)。因此,result1 的长度为 255 而不是 169。
    • 我遇到了同样的问题;异常中的整个 EOF 事情让我感到震惊,我的问题只是纯粹且简单的格式错误的 JSON。
    • 我遇到了同样的问题,但是我通过 FileChannel 获得了我的 JSON。我很确定编码没问题。我所做的是从硬盘上的文件中调用 String red 的 trim() 方法,这解决了问题。
    • @ThePaul - 您的字符串末尾可能有额外的 NUL(即 '\0')字符。 String.trim() 不仅删除空格,还删除任何小于 32 的字符,而 GSON 将这些字符视为尾随垃圾。 (然后它抱怨“我看到了右括号,所以接下来应该看到一个 EOF,但我看到了一些其他的东西”)
    • 确保你正在导入正确的 json 阅读器,其他库具有相同名称的类
    【解决方案2】:

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

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

    String trimmed = result1.trim();
    

    那么gson.fromJson(trimmed, T) 可能会起作用。当然,这只涵盖了一种特殊情况,所以 YMMV。

    【讨论】:

    • 嗨@ryenus,如果我有两个单词中间有空格,那该怎么办?
    • 如果空格在字符串响应中很重要怎么办?在这种情况下,tirming 是不好的。您将失去数据的完整性。
    【解决方案3】:

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

    在java代码中你需要转义特殊字符

    【讨论】:

    • 我从调试器中复制了 result1 的值,然后添加了反斜杠以转义 result2 中的特殊字符;)
    • 是否有空格字符或 \n\r 前面或附加到 json 字符串。应该很简单
    • result1.equals(result2)的结果是什么?
    • @ProgrammerBruce:result1.equals(result2)=false。两个字符串都包含相同的字符,但 result1 比 result2 长(由我的 http 类引起;见上文)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2023-04-03
    • 1970-01-01
    • 2017-12-10
    • 2012-04-21
    • 1970-01-01
    相关资源
    最近更新 更多