205

How do I validate a JSON string in Java? Or could I parse it using regular expressions?

kba
  • 19,333
  • 5
  • 62
  • 89
sappu
  • 6,665
  • 4
  • 19
  • 18

20 Answers20

318

A wild idea, try parsing it and catch the exception:

import org.json.*;

public boolean isJSONValid(String test) {
    try {
        new JSONObject(test);
    } catch (JSONException ex) {
        // edited, to include @Arthur's comment
        // e.g. in case JSONArray is valid as well...
        try {
            new JSONArray(test);
        } catch (JSONException ex1) {
            return false;
        }
    }
    return true;
}

This code uses org.json JSON API implementation that is available on github, in maven and partially on Android.

Zoe
  • 27,060
  • 21
  • 118
  • 148
MByD
  • 135,866
  • 28
  • 264
  • 277
  • 2
    It is close, but is missing a validation for a JSONArray (i've updated this post with a more suitable function) – Arthur Dec 06 '13 at 20:48
  • @Arthur where is your better solution? I'm using 'new JSONObject(test)' and it doesn't work for json arrays. – mtmurdock Jun 05 '14 at 15:12
  • @mtmurdock - for some reason Arthur's edit is not here, I updated it, and hope it will work for you now – MByD Jun 05 '14 at 17:42
  • Hmmm...i thought i edited it (maybe forgot to press seve?) :/ Oh well, at least everyone got the point :D – Arthur Jun 06 '14 at 14:24
  • 12
    I've tried a json string like "{'hello':'foo'} 'invalid'" (added 'invalid' outside the {}), and JSONObject is not throwing ParseException. I am using org.json.JSONObject. Is this expected? – Soichi Hayashi Aug 21 '14 at 22:40
  • 18
    You didn't mention library that has JSONObject, I didn't seen it in standard java lib – Krzysztof Krasoń Feb 09 '15 at 15:29
  • 1
    I think he's using [JSON-simple](https://code.google.com/p/json-simple/) by Google – Porthos3 Jun 23 '15 at 16:35
  • 1
    it fails with huge json strings – Valentino Ru Jul 20 '15 at 22:59
  • 7
    This solution works for most cases, but could fail in certain circumstances. For example, it allows the comma right before the closing brace, which actually is a syntax error. Refer to http://www.json.org/javadoc/org/json/JSONObject.html for other corner cases. – Hua2308 Sep 29 '15 at 18:00
  • see this http://stackoverflow.com/questions/38890526/trailing-characters-getting-parsed-in-json/38892378#38892378 – iec2011007 Aug 11 '16 at 09:33
  • The response string can also be "Nil" .if(test== null) return false; is also needed. – VARUN ISAC Mar 22 '17 at 08:40
  • 10
    I can't understand why posters can't be bothered to include import statements with code snippets. It's important here. The second-rated answer here is *much* better. – seansand Sep 29 '17 at 22:34
  • We should avoid using try/catch. This solution will work for all the cases. Just check my answer at this link https://stackoverflow.com/a/56357829/6481933 – Sanjay Kushwah May 29 '19 at 11:04
  • @SanjayKushwah - I wasn't aware of this class, however, it seems that this API, too, raises exception if the string is not a valid JSON. (according to docs) – MByD May 29 '19 at 16:39
  • @MByD If It will be null so it will not fullfil the `if block` condition and it will go into else block. So there will not be any crash there. – Sanjay Kushwah May 30 '19 at 12:18
  • @SanjayKushwah - the problem is not with null, but with an invalid json string. moreover - this package is not part of the standard java library, and is built-in only for android. I can't event check it with standard java installation. – MByD Jun 02 '19 at 07:26
  • The maven link doesn't work on firefox. `Unable to connect. Firefox can’t establish a connection to the server at maven-repository.com.` – byxor Oct 28 '19 at 14:50
  • @Hua2308 this can cause a problem if we use `gson.fromJson(..., ...)` – YoussefDir Mar 31 '20 at 20:42
  • This library has very lax parsing rules, which allows it to parse even invalid JSON, this answer should really not be accepted, or at least have it mentioned in the answer. The library allows unquoted strings, numbers, extra commas, all of which are not valid in a strict JSON format. – Omri Luzon Jul 15 '20 at 09:41
  • I think this is not 100% correct, below example is not valid json but above code will create valid json with below input. { "name" : mkj123 } – Jangid May 19 '21 at 13:55
  • another idea: why not counting the occurrence of `{` and `}` , and if not a match, it's invalid json. Could that work? if validating the "structure" ? – Sam Aug 11 '21 at 16:16
  • What I have tested: `{"vehicleInformation":{"PopupMessage":{"Title":"some Information","Lines":["line1","line2","line3","line4."],"Controls":[{"label":"Cancel","state":"Normal"},{"label":"Reset","state":"Normal"}]}}}{"Gauges":{"DisplayType":{"GUIDisplay"`, which is invalid json. I got no exception!! and when printing out the returned json, this is what I got: `{"vehicleInformation":{"PopupMessage":{"Title":"some Information","Lines":["line1","line2","line3","line4."],"Controls":[{"label":"Cancel","state":"Normal"},{"label":"Reset","state":"Normal"}]}}}`. it cuts off the json! – Sam Aug 11 '21 at 17:31
  • I always understood that Exceptions should be used for exceptional circumstances ([for example](https://learn.microsoft.com/en-us/dotnet/standard/exceptions/best-practices-for-exceptions#handle-common-conditions-without-throwing-exceptions)) rather than for common or expected code paths. – John Darvill Aug 03 '23 at 15:00
125

JACKSON Library

One option would be to use Jackson library. First import the latest version (now is):

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.7.0</version>
</dependency>

Then, you can implement the correct answer as follows:

import com.fasterxml.jackson.databind.ObjectMapper;

public final class JSONUtils {
  private JSONUtils(){}

  public static boolean isJSONValid(String jsonInString ) {
    try {
       final ObjectMapper mapper = new ObjectMapper();
       mapper.readTree(jsonInString);
       return true;
    } catch (IOException e) {
       return false;
    }
  }
}

Google GSON option

Another option is to use Google Gson. Import the dependency:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.5</version>
</dependency>

Again, you can implement the proposed solution as:

import com.google.gson.Gson;

public final class JSONUtils {
  private static final Gson gson = new Gson();

  private JSONUtils(){}

  public static boolean isJSONValid(String jsonInString) {
      try {
          gson.fromJson(jsonInString, Object.class);
          return true;
      } catch(com.google.gson.JsonSyntaxException ex) { 
          return false;
      }
  }
}

A simple test follows here:

//A valid JSON String to parse.
String validJsonString = "{ \"developers\": [{ \"firstName\":\"Linus\" , \"lastName\":\"Torvalds\" }, " +
        "{ \"firstName\":\"John\" , \"lastName\":\"von Neumann\" } ]}";

// Invalid String with a missing parenthesis at the beginning.
String invalidJsonString = "\"developers\": [ \"firstName\":\"Linus\" , \"lastName\":\"Torvalds\" }, " +
        "{ \"firstName\":\"John\" , \"lastName\":\"von Neumann\" } ]}";

boolean firstStringValid = JSONUtils.isJSONValid(validJsonString); //true
boolean secondStringValid = JSONUtils.isJSONValid(invalidJsonString); //false

Please, observe that there could be a "minor" issue due to trailing commas that will be fixed in release 3.0.0.

YoussefDir
  • 287
  • 1
  • 3
  • 16
JeanValjean
  • 17,172
  • 23
  • 113
  • 157
  • While this works for big things like mismatched quotes, or missing parentheses, Gson will happily parse a json array with a trailing comma, which does not comply with [RFC-4627](http://www.ietf.org/rfc/rfc4627.txt) – Ch4ni Dec 29 '14 at 18:14
  • @eurythmia True! In version 3.0 they should [fix the issue](https://github.com/google/gson/issues/494) – JeanValjean Jan 25 '16 at 17:13
  • 1
    This validates { key: value } too, but its not a valid json – Hemant Patel Jun 19 '16 at 05:42
  • @Hemant That's true for _Gson's validator_, that has some bugs supposed to be fixed starting from release `3.0.0` (now is `2.7`). I recommend to use the _Jackson's validation_ method, that works very very well. – JeanValjean Jun 19 '16 at 06:40
  • 5
    JACKSON pitfall: `new ObjectMapper().readTree("28xjRBuOQqupRopHeSuhRQ")` parses without Exception as IntNode(28). Not really expected... – mgaert Mar 02 '18 at 13:13
  • 1
    As I understand this solution not only validates, but parses (and stores) the whole json. It converts numbers to Integer/Long/Double etc. This is more than just syntax check, it stores whole json in the memory. This might be significant for intensive loads. If better solution for syntax check exists? – Oleg Vazhnev Dec 19 '18 at 10:33
  • 2
    Beware that gson example here uses [lenient](https://static.javadoc.io/com.google.code.gson/gson/2.8.5/com/google/gson/stream/JsonReader.html#setLenient-boolean-) parsing mode which still allows many deviations. See [more details with testcase](https://stackoverflow.com/questions/43233898/how-to-check-if-json-is-valid-in-java-using-gson/47890960#47890960) and [strict parsing example](https://stackoverflow.com/questions/10174898/how-to-check-whether-a-given-string-is-valid-json-in-java/56901432#56901432) in my other answers. – Vadzim Jul 05 '19 at 10:42
  • Don’t forget to enable the feature FAIL_ON_TRAILING_TOKENS with Jackson!!! – CidTori May 05 '22 at 18:23
16

With Google Gson you can use JsonParser:

import com.google.gson.JsonParser;

JsonParser parser = new JsonParser();
parser.parse(json_string); // throws JsonSyntaxException
Cristian
  • 161
  • 1
  • 4
  • 3
    Note that this doesn't throw an error on unbracketed strings ala "asdf" – Andrew Jan 14 '16 at 23:00
  • 1
    Nor does it reject trailing commas in JSON arrays. – Sotirios Delimanolis Jun 22 '16 at 20:19
  • I can't really trust on that... it says that the string "Save" is parseable. – Dherik Nov 07 '17 at 17:07
  • Beware that gson example here uses [lenient](https://static.javadoc.io/com.google.code.gson/gson/2.8.5/com/google/gson/stream/JsonReader.html#setLenient-boolean-) parsing mode which still allows many deviations. See [more details with testcase](https://stackoverflow.com/questions/43233898/how-to-check-if-json-is-valid-in-java-using-gson/47890960#47890960) and [strict parsing example](https://stackoverflow.com/questions/10174898/how-to-check-whether-a-given-string-is-valid-json-in-java/56901432#56901432) in my other answers. – Vadzim Jul 05 '19 at 10:42
15

You could use the .mayBeJSON(String str) available in the JSONUtils library.

npinti
  • 51,780
  • 5
  • 72
  • 96
  • yes...this is working. Thanks npinti. i was trying with gson but there no such method i have seen. – sappu Apr 16 '12 at 13:34
  • @sappu: If this answer solved your question then mark it so. Most libraries tend to take in a String and try to parse it, if the parsing fails, that is, the string is not a valid JSON string, it will throw an exception. – npinti Apr 16 '12 at 13:36
  • @npinti: Failed for extra }. Returns true for invalid string with extra bracket => } – Vivek Mar 12 '14 at 09:25
  • 3
    This method literally only checks that the string begins and ends with either quotes or brackets. Very unreliable. – Michael Munsey Aug 01 '16 at 18:51
  • 3
    that's why the method name is 'maybe', not 'is' :) – Khoa Mar 14 '17 at 23:35
  • Useful, when test first then parse, `if ! .mayBeJSON(str){ log(str as error)}else{ parseJSON(str)} ` – Yu Jiaao Jan 29 '18 at 06:20
  • https://github.com/jenkinsci/json-lib/blob/master/src/main/java/net/sf/json/util/JSONUtils.java#L387 – Vlad May 28 '20 at 08:41
5

It depends on what you are trying to prove with your validation. Certainly parsing the json as others have suggested is better than using regexes, because the grammar of json is more complicated than can be represented with just regexes.

If the json will only ever be parsed by your java code, then use the same parser to validate it.

But just parsing won't necessarily tell you if it will be accepted in other environments. e.g.

  • many parsers ignore trailing commas in an object or array, but old versions of IE can fail when they hit a trailing comma.
  • Other parsers may accept a trailing comma, but add an undefined/null entry after it.
  • Some parsers may allow unquoted property names.
  • Some parsers may react differently to non-ASCII characters in strings.

If your validation needs to be very thorough, you could:

Nicholas Daley-Okoye
  • 2,267
  • 1
  • 18
  • 12
4
String jsonInput = "{\"mob no\":\"9846716175\"}";//Read input Here
JSONReader reader = new JSONValidatingReader();
Object result = reader.read(jsonInput);
System.out.println("Validation Success !!");

Please download stringtree-json library

Jamsheer
  • 3,673
  • 3
  • 29
  • 57
4

A bit about parsing:

Json, and in fact all languages, use a grammar which is a set of rules that can be used as substitutions. in order to parse json, you need to basically work out those substitutions in reverse

Json is a context free grammar, meaning you can have infinitely nested objects/arrays and the json would still be valid. regex only handles regular grammars (hence the 'reg' in the name), which is a subset of context free grammars that doesn't allow infinite nesting, so it's impossible to use only regex to parse all valid json. you could use a complicated set of regex's and loops with the assumption that nobody will nest past say, 100 levels deep, but it would still be very difficult.

if you ARE up for writing your own parser
you could make a recursive descent parser after you work out the grammar

Austin_Anderson
  • 900
  • 6
  • 16
4

Check whether a given string is valid JSON in Kotlin. I Converted answer of MByD Java to Kotlin

fun isJSONValid(test: String): Boolean {
    try {
        JSONObject(test);
    } catch (ex: JSONException) {
        try {
            JSONArray(test);
        } catch (ex1: JSONException) {
            return false;
        }
    }
    return true;
}
Bhavesh Hirpara
  • 22,255
  • 15
  • 63
  • 104
4

Here is a working example for strict json parsing with gson library:

public static JsonElement parseStrict(String json) {
    // throws on almost any non-valid json
    return new Gson().getAdapter(JsonElement.class).fromJson(json); 
}

See also my other detailed answer in How to check if JSON is valid in Java using GSON with more info and extended test case with various non-valid examples.

Vadzim
  • 24,954
  • 11
  • 143
  • 151
3

The answers are partially correct. I also faced the same problem. Parsing the json and checking for exception seems the usual way but the solution fails for the input json something like

{"outputValueSchemaFormat": "","sortByIndexInRecord": 0,"sortOrder":847874874387209"descending"}kajhfsadkjh

As you can see the json is invalid as there are trailing garbage characters. But if you try to parse the above json using jackson or gson then you will get the parsed map of the valid json and garbage trailing characters are ignored. Which is not the required solution when you are using the parser for checking json validity.

For solution to this problem see here.

PS: This question was asked and answered by me.

Community
  • 1
  • 1
iec2011007
  • 1,828
  • 3
  • 24
  • 38
3

A solution using the javax.json library:

import javax.json.*;

public boolean isTextJson(String text) {
    try {
        Json.createReader(new StringReader(text)).readObject();
    } catch (JsonException ex) {
        try {
            Json.createReader(new StringReader(text)).readArray();
        } catch (JsonException ex2) {
            return false;
        }
    }
    return true;
}
Rok Povsic
  • 4,626
  • 5
  • 37
  • 53
  • May I ask why did you two separate readers. I tried with `Json.createReader(new StringReader(text)).read()` and it seems to be working fine. Is there a case where it fails? – Knu8 Jun 01 '21 at 14:11
  • 1
    @Knu8 I think using `read` should work completely fine as well. – Rok Povsic Jun 02 '21 at 05:04
2

As you can see, there is a lot of solutions, they mainly parse the JSON to check it and at the end you will have to parse it to be sure.

But, depending on the context, you may improve the performances with a pre-check.

What I do when I call APIs, is just checking that the first character is '{' and the last is '}'. If it's not the case, I don't bother creating a parser.

Orden
  • 589
  • 3
  • 13
1

Here you can find a tool that can validate a JSON file, or you could just deserialize your JSON file with any JSON library and if the operation is successful then it should be valid (google-json for example that will throw an exception if the input it is parsing is not valid JSON).

talnicolas
  • 13,885
  • 7
  • 36
  • 56
1

Using Playframework 2.6, the Json library found in the java api can also be used to simply parse the string. The string can either be a json element of json array. Since the returned value is not of importance here we just catch the parse error to determine that the string is a correct json string or not.

    import play.libs.Json;

    public static Boolean isValidJson(String value) {
        try{
            Json.parse(value);
            return true;
        } catch(final Exception e){
            return false;
        }
    }
Baah
  • 31
  • 5
1

IMHO, the most elegant way is using the Java API for JSON Processing (JSON-P), one of the JavaEE standards that conforms to the JSR 374.

try(StringReader sr = new StringReader(jsonStrn)) {
    Json.createReader(sr).readObject();
} catch(JsonParsingException e) {
    System.out.println("The given string is not a valid json");
    e.printStackTrace();
}

Using Maven, add the dependency on JSON-P:

<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.json</artifactId>
    <version>1.1.4</version>
</dependency>

Visit the JSON-P official page for more informations.

Domenico
  • 1,331
  • 18
  • 22
1

in Gson Version

try {
    String errorBody = response.errorBody().string();
    MyErrorResponse errorResponse = new Gson().fromJson(errorBody, MyErrorResponse.class);
} catch (JsonSyntaxException e) {
    e.printStackTrace();
}
Yi Rong Wu
  • 21
  • 3
0

I have found a very simple solution for it.

Please first install this library net.sf.json-lib for it.

    import net.sf.json.JSONException;

    import net.sf.json.JSONSerializer;

    private static boolean isValidJson(String jsonStr) {
        boolean isValid = false;
        try {
            JSONSerializer.toJSON(jsonStr);
            isValid = true;
        } catch (JSONException je) {
            isValid = false;
        }
        return isValid;
    }

    public static void testJson() {
        String vjson = "{\"employees\": [{ \"firstName\":\"John\" , \"lastName\":\"Doe\" },{ \"firstName\":\"Anna\" , \"lastName\":\"Smith\" },{ \"firstName\":\"Peter\" , \"lastName\":\"Jones\" }]}";
        String ivjson = "{\"employees\": [{ \"firstName\":\"John\" ,, \"lastName\":\"Doe\" },{ \"firstName\":\"Anna\" , \"lastName\":\"Smith\" },{ \"firstName\":\"Peter\" , \"lastName\":\"Jones\" }]}";
        System.out.println(""+isValidJson(vjson)); // true
        System.out.println(""+isValidJson(ivjson)); // false
    }

Done. Enjoy

sundar nataraj
  • 8,524
  • 2
  • 34
  • 46
0
import static net.minidev.json.JSONValue.isValidJson;

and then call this function passing in your JSON String :)

Jason
  • 193
  • 2
  • 12
0
public static boolean isJSONValid(String test) {
    try {
        isValidJSON(test);
        JsonFactory factory = new JsonFactory();
        JsonParser parser = factory.createParser(test);
        while (!parser.isClosed()) {
            parser.nextToken();
        }
    } catch (Exception e) {
        LOGGER.error("exception: ", e);
        return false;
    }
    return true;
}

private static void isValidJSON(String test) {
    try {
        new JSONObject(test);
    } catch (JSONException ex) {
        try {
            LOGGER.error("exception: ", ex);
            new JSONArray(test);
        } catch (JSONException ex1) {
            LOGGER.error("exception: ", ex1);
            throw new Exception("Invalid JSON.");
        }
    }
}

Above solution covers both the scenarios:

  • duplicate key
  • mismatched quotes or missing parentheses etc.
Shailendra
  • 61
  • 1
  • 5
0

You can try below code, worked for me:

 import org.json.JSONObject;
 import org.json.JSONTokener;

 public static JSONObject parseJsonObject(String substring)
 {
  return new JSONObject(new JSONTokener(substring));
 }
dicle
  • 1,122
  • 1
  • 12
  • 40