“预期BEGIN_OBJECT,但在第 1 行第 1 列是字符串”

2022-08-31 06:43:13

我有这个方法:

public static Object parseStringToObject(String json) {
    String Object = json;
    Gson gson = new Gson();
    Object objects = gson.fromJson(object, Object.class);
    parseConfigFromObjectToString(object);
    return objects;
}

我想用以下方式解析一个JSON:

public static void addObject(String IP, Object addObject) {
    try {
        String json = sendPostRequest("http://" + IP + ":3000/config/add_Object", ConfigJSONParser.parseConfigFromObjectToString(addObject));
        addObject = ConfigJSONParser.parseStringToObject(json);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

但是我收到一条错误消息:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT,但在第 1 列第 1 列处是 STRING


答案 1

即使没有看到 JSON 字符串,您也可以从错误消息中看出,它不是要解析为类实例的正确结构。

Gson 期望您的 JSON 字符串以对象左大括号开头。例如:

{

但是您传递给它的字符串以未开引号开头

"

答案 2

来自服务器的无效 JSON 应始终是预期的用例。在传输过程中,有一百万件事情可能会出错。Gson有点棘手,因为它的错误输出会给你一个问题,而你捕捉到的实际异常将是不同类型的。

考虑到所有这些,客户端的正确修复是

try
{
  gson.fromJSON(ad, Ad.class);
  //...
}
catch (IllegalStateException | JsonSyntaxException exception)
{
  //...

如果您想知道为什么从服务器收到的 JSON 是错误的,可以在异常处查看 catch 块内部。但是,即使这是您的问题,客户端也没有责任修复从互联网接收的JSON。

无论哪种方式,客户端都有责任决定在JSON错误时该怎么办。两种可能性是拒绝 JSON 和什么都不做,然后重试。

如果您要再次尝试,我强烈建议在 try / catch 块内设置一个标志,然后在 try / catch 块之外响应该标志。嵌套尝试/捕获可能是Gson如何让我们陷入这种混乱,我们的堆栈跟踪和异常不匹配。

换句话说,即使我承认它看起来不是很优雅,我也会推荐

boolean failed = false;

try
{
  gson.fromJSON(ad, Ad.class);
  //...
}
catch (IllegalStateException | JsonSyntaxException exception)
{
  failed = true;
  //...
}

if (failed)
{
  //...