gson 抛出 MalformedJsonException
Posted
技术标签:
【中文标题】gson 抛出 MalformedJsonException【英文标题】:gson throws MalformedJsonException 【发布时间】:2012-07-14 02:56:48 【问题描述】:我正在使用 gson 将 json 字符串转换为 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;
【问题讨论】:
【参考方案1】:我怀疑 result1 末尾有一些字符,您在调试器中看不到关闭 字符之后的字符。
result1
与 result2
的长度是多少?我会注意到您引用的 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 类引起;见上文)。以上是关于gson 抛出 MalformedJsonException的主要内容,如果未能解决你的问题,请参考以下文章
在Grails中使用带有rest配置文件的gson时,String列表抛出ClassCastException
为啥 Gson fromJson 会抛出 JsonSyntaxException: Expected BEGIN_OBJECT but was BEGIN_ARRAY?