如何修复com.google.gson.stream.MalformedJsonException异常
问题根源与解决方案
你遇到的这个JsonSyntaxException本质上是因为你的JSON数据源格式不合法——看你提供的示例数据,它是两个独立的JSON对象直接拼在一起,既没有用数组[]包裹,对象之间也没有逗号分隔,这不符合标准JSON的语法规范,所以Gson的解析器会判定这是格式错误的JSON。
为什么会报错?
标准JSON要求整个文档要么是单个对象({...}),要么是一个数组([{...}, {...}])。但你的数据是:
{"address":"P.O. Box 939",...} {"address":"PO Box 6479",...}
两个对象直接相连,解析器读完第一个对象后,遇到第二个对象的{就会判定为语法错误,这就是你看到MalformedJsonException的核心原因。
解决方案
根据你的情况,有两种可行的处理方式:
方案1:修改数据源为标准JSON数组(推荐,如果能控制数据源的话)
把数据改成数组格式,用[]包裹所有对象,对象之间用逗号分隔:
[ {"address":"P.O. Box 939","city":"Indian River",...}, {"address":"PO Box 6479","city":"Silver Spring",...} ]
修改后,你原来的代码只需要微调就能正常解析,比如直接把根节点解析成JsonArray:
URL url = new URL("你的目标URL"); URLConnection request = url.openConnection(); request.connect(); JsonParser jp = new JsonParser(); JsonArray rootArray = jp.parse(new InputStreamReader((InputStream) request.getContent())).getAsJsonArray(); // 遍历数组处理每个对象 for (JsonElement element : rootArray) { JsonObject rootobj = element.getAsJsonObject(); JSONObject jsonObject = new JSONObject(rootobj.toString()); // 这里编写你的业务处理逻辑 }
方案2:按JSON Lines格式解析(如果无法修改数据源)
你的数据其实符合JSON Lines格式(每行一个独立的JSON对象),这种情况下可以逐行读取并解析每个对象:
URL url = new URL("你的目标URL"); URLConnection request = url.openConnection(); request.connect(); try (BufferedReader reader = new BufferedReader(new InputStreamReader((InputStream) request.getContent()))) { String line; JsonParser jp = new JsonParser(); while ((line = reader.readLine()) != null) { // 跳过空行避免解析错误 if (line.trim().isEmpty()) continue; JsonObject rootobj = jp.parse(line).getAsJsonObject(); JSONObject jsonObject = new JSONObject(rootobj.toString()); // 处理每个对象的业务逻辑 } } catch (IOException e) { e.printStackTrace(); }
关于JsonReader.setLenient(true)的说明
错误提示里提到的这个设置,是用来兼容一些非标准的JSON语法(比如末尾多余的逗号、注释等),但它解决不了你这种结构上的错误——即使开启宽松模式,解析器也无法正确识别两个拼接的对象,反而可能会把第二个对象的内容错误附加到第一个对象上,所以不建议用这个方法来解决你的问题。
内容的提问来源于stack exchange,提问作者Geo Thomas
相关产品推荐
相关产品推荐

