I have method that have to check if JSON is valid, found on How to check whether a given string is valid JSON in Java but it doesn't work.
public static boolean isJson(String Json) {
Gson gson = new Gson();
try {
gson.fromJson(Json, Object.class);
return true;
} catch (com.google.gson.JsonSyntaxException ex) {
return false;
}
}
If I use this method with some string it always returns true. For example:
System.out.println(renderHtml.isJson("{\"status\": \"UP\"}"));
it gave me true
, and
System.out.println(renderHtml.isJson("bncjbhjfjhj"));
gave me true
also.
The simplest way to check if JSON is valid is to load the JSON into a JObject or JArray and then use the IsValid(JToken, JSchema) method with the JSON Schema. To get validation error messages use the IsValid(JToken, JSchema, IList<String> ) or Validate(JToken, JSchema, SchemaValidationEventHandler) overloads.
The common approach for checking if a String is a valid JSON is exception handling. Consequently, we delegate JSON parsing and handle the specific type of error in case of incorrect value or assume that value is correct if no exception occurred.
The JSON format was originally specified by Douglas Crockford. On the other hand, GSON is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object.
Is a plain string valid JSON or does there have to be an object? Yes, it is.
You should not use Gson
to make such validation:
Gson
is an object that performs deserialization therefore it deserializes entire JSON as an object in memory.Gson
, and I didn't know it, may be not very strict for some invalid JSONs: bncjbhjfjhj
is deserialized as a java.lang.String
instance. Surprise-surprise!private static final Gson gson = new Gson();
private static final String VALID_JSON = "{\"status\": \"UP\"}";
private static final String INVALID_JSON = "bncjbhjfjhj";
System.out.println(gson.fromJson(VALID_JSON, Object.class).getClass());
System.out.println(gson.fromJson(INVALID_JSON, Object.class).getClass());
Output:
class com.google.gson.internal.LinkedTreeMap
class java.lang.String
What you can do here is using JsonReader
to read incoming JSON token by token thus making if the given JSON document is syntactically valid.
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;
loop:
while ( (token = jsonReader.peek()) != END_DOCUMENT && token != null ) {
switch ( token ) {
case BEGIN_ARRAY:
jsonReader.beginArray();
break;
case END_ARRAY:
jsonReader.endArray();
break;
case BEGIN_OBJECT:
jsonReader.beginObject();
break;
case END_OBJECT:
jsonReader.endObject();
break;
case NAME:
jsonReader.nextName();
break;
case STRING:
case NUMBER:
case BOOLEAN:
case NULL:
jsonReader.skipValue();
break;
case END_DOCUMENT:
break loop;
default:
throw new AssertionError(token);
}
}
return true;
} catch ( final MalformedJsonException ignored ) {
return false;
}
}
And then test it:
System.out.println(isJsonValid(VALID_JSON));
System.out.println(isJsonValid(INVALID_JSON));
Output:
true
false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With