Gson:JsonParser.parse()无法识别无效的JSON格式

时间:2017-04-21 12:52:47

标签: java json parsing gson

我想使用com.google.gson.JsonParser验证JSON字符串。通过此post,我知道JsonParser.parse()足够宽松,可以将无效的 abc 视为有效的" abc" 。也就是说,JsonParser.parse()不会为下面的字符串抛出JsonSyntaxExceptionJsonParseException

abc

通过添加 jsonElement.isJsonObject()的逻辑,以下代码可以识别 abc 的无效JSON字符串。

boolean isJSON(String jsonString) {

  try {
    JsonElement jsonElement = new JsonParser().parse(jsonString);

    if (!jsonElement.isJsonObject()) {
      return false;
    }
  } catch (Exception e) {
    return false;
  }

  return true;
}

但是,它仍然无法从以下字符串中识别出无效的JSON格式。

{"name": mike}

{name: mike}

如何识别这些案例的无效JSON?

1 个答案:

答案 0 :(得分:1)

出于以下几个原因,您不应该使用JsonParser

  • 它使用了宽大的JsonReader
  • 它在内存中创建了一个JSON文档视图(JsonElement),这对于不小的文档来说绝对不是一种方法。

您可以安全地使用JsonReader

private static boolean isJsonValid(final String json)
        throws IOException {
    return isJsonValid(new StringReader(json));
}

private static boolean isJsonValid(final Reader reader)
        throws IOException {
    return isJsonValid(new JsonReader(reader));
}

private static boolean isJsonValid(final JsonReader jsonReader)
        throws IOException {
    try {
        JsonToken token;
        while ( (token = jsonReader.peek()) != END_DOCUMENT && token != null ) {
            skipToken(jsonReader);
        }
        return true;
    } catch ( final MalformedJsonException ignored ) {
        return false;
    }
}

// Maybe skipToken will be a part of Gson someday: https://github.com/google/gson/issues/1054
private static void skipToken(final JsonReader reader)
        throws IOException {
    final JsonToken token = reader.peek();
    switch ( token ) {
    case BEGIN_ARRAY:
        reader.beginArray();
        break;
    case END_ARRAY:
        reader.endArray();
        break;
    case BEGIN_OBJECT:
        reader.beginObject();
        break;
    case END_OBJECT:
        reader.endObject();
        break;
    case NAME:
        reader.nextName();
        break;
    case STRING:
    case NUMBER:
    case BOOLEAN:
    case NULL:
        reader.skipValue();
        break;
    case END_DOCUMENT:
    default:
        throw new AssertionError(token);
    }
}

测试:

public static void main(final String... args)
        throws IOException {
    System.out.println(isJsonValid("\"abc\""));
    System.out.println(isJsonValid("{\"name\": \"mike\"}"));
    System.out.println(isJsonValid("abc"));
    System.out.println(isJsonValid("{\"name\": mike}"));
    System.out.println(isJsonValid("{name: mike}"));
    System.out.println(isJsonValid("{name: \"mike\"}"));
}

上述测试产生:

  


  真正
  假
  假
  假
  假的