1

I want to validate a JSON string by using com.google.gson.JsonParser. By this post, I know that JsonParser.parse() is lenient enough to treat invalid abc as valid "abc". That is to say, JsonParser.parse() will not throw a JsonSyntaxException or JsonParseException for the string below:

abc

By adding the logic of jsonElement.isJsonObject(), the following code can recognize invalid JSON string of abc.

boolean isJSON(String jsonString) {

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

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

  return true;
}

However, it still cannot recognize invalid JSON format from the following strings.

{"name": mike}

or

{name: mike}

How to recognize invalid JSON for these cases?

1
  • I'm not going to modify 3rd party code, neither am I able to change the input string. I just want to make a strong JSON validation. Commented Apr 21, 2017 at 13:01

1 Answer 1

1

You should not use JsonParser for a couple of reasons:

  • It uses lenient JsonReader under the hood.
  • It creates a JSON document view in memory (JsonElement) that is definitely not a way to go for not small documents.

You can use JsonReader safely:

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);
    }
}

Test:

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\"}"));
}

The test above produces:

true
true
false
false
false
false

Sign up to request clarification or add additional context in comments.

4 Comments

@yasi Hm, I'm not at the desktop at the moment, but the code line you mentioned should print true according to the JSON spec, and the test prints the same. Or am I missing something?
I was typing too long. :)
Yes, the code should print true for "abc", my mistake. However, by reading json.org (the legend on right side of it), I think "abc" is invalid JSON format string since any JSON "object" begins with "{" and ends with "}". However, online JSON validator, jsonlint.com , validates it's valid JSON string. Please help me out for the confusion.
@yasi Please see: stackoverflow.com/questions/18419428/… - it's confusing me though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.