如何在Java中检查给定字符串是否是有效的JSON

时间:2012-04-16 13:16:20

标签: java json validation

如何在Java中验证JSON字符串?或者我可以使用正则表达式解析它吗?

20 个答案:

答案 0 :(得分:236)

一个疯狂的想法,尝试解析它并捕获异常:

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

此代码使用可用的org.json JSON API实现on githubin maven和部分on Android

答案 1 :(得分:75)

JACKSON Library

一种选择是使用Jackson library。首先导入最新版本(现在是):

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

然后,您可以按如下方式实施correct answer

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选项

另一种选择是使用Google Gson。导入依赖项:

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

同样,您可以将建议的解决方案实施为:

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 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(VALID_JSON_STRING); //true
boolean secondStringValid = JSONUtils.isJSONValid(NOT_VALID_JSON_STRING); //false

请注意,可能会有一个&#34;未成年人&#34;因尾随逗号而导致的问题将在版本3.0.0中修复。

答案 2 :(得分:14)

使用Google Gson,您可以使用JsonParser:

import com.google.gson.JsonParser;

JsonParser parser = new JsonParser();
parser.parse(json_string); // throws JsonSyntaxException

答案 3 :(得分:11)

您可以使用.mayBeJSON(String str)库中提供的JSONUtils

答案 4 :(得分:5)

这取决于您尝试通过验证证明的内容。 当然,正如其他人所建议的那样解析json比使用正则表达式更好,因为json的语法比只用正则表达式表示的更复杂。

如果json只会被你的java代码解析,那么使用相同的解析器来验证它。

但只是解析不一定会告诉你它是否会在其他环境中被接受。例如

  • 许多解析器忽略对象或数组中的尾随逗号,但旧版本的IE在遇到尾随逗号时可能会失败。
  • 其他解析器可以接受尾随逗号,但在其后面添加一个未定义的/ null条目。
  • 某些解析器可能允许不带引号的属性名称。
  • 某些解析器可能会对字符串中的非ASCII字符做出不同的反应。

如果您的验证需要非常彻底,您可以:

答案 5 :(得分:4)

String jsonInput = "{\"mob no\":\"9846716175\"}";//Read input Here
JSONReader reader = new JSONValidatingReader();
Object result = reader.read(jsonInput);
System.out.println("Validation Success !!");

请下载 stringtree-json

答案 6 :(得分:2)

关于解析的一点:

Json,实际上所有语言都使用语法,这是一组可用作替换的规则。为了解析json,你需要基本上反过来计算那些替换

Json是一个上下文无关语法,这意味着你可以拥有无​​限嵌套的对象/数组,json仍然有效。正则表达式只处理常规语法(因此名称中的&#39; reg&#39;),它是不允许无限嵌套的上下文无关语法的子集,所以它&#39 ;不可能只使用正则表达式来解析所有有效的json。你可以使用一套复杂的正则表达式和循环,假设没有人会过去说100级深度,但这仍然非常困难。

如果您要编写自己的解析器
你可以在编制语法后制作一个递归下降解析器

答案 7 :(得分:1)

使用Playframework 2.6,java api中的Json库也可以用来简单地解析字符串。该字符串可以是json数组的json元素。由于返回值在这里不重要,我们只是捕获解析错误以确定该字符串是否是正确的json字符串。

    import play.libs.Json;

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

答案 8 :(得分:1)

Kotlin 中检查给定的字符串是否为有效的JSON。我将MByD Java的答案转换为Kotlin

fun isJSONValid(test: String): Boolean {
    try {
        JSONObject(test);
    } catch (ex: JSONException) {
        try {
            JSONArray(test);
        } catch (ex1: JSONException) {
            return false;
        }
    }
    return true;
}

答案 9 :(得分:1)

在这里你可以找到一个可以验证JSON文件的tool,或者你可以用任何JSON库反序列化你的JSON文件,如果操作成功,那么它应该是有效的(google-json for如果它正在解析的输入是无效的JSON,则抛出异常的示例。

答案 10 :(得分:0)

答案部分正确。我也遇到了同样的问题。解析json并检查异常似乎是通常的方法,但解决方案失败了输入json类似

{&#34; outputValueSchemaFormat&#34;:&#34;&#34;,&#34; sortByIndexInRecord&#34;:0,&#34; sortOrder&#34;:847874874387209&#34;降序& #34;} kajhfsadkjh

正如您所看到的那样,json无效,因为存在尾随垃圾字符。但是如果您尝试使用jackson或gson解析上面的json,那么您将获得有效json的解析映射,并忽略垃圾尾随字符。当您使用解析器检查json有效性时,这不是必需的解决方案。

要解决此问题,请参阅here

PS:这个问题是由我提出并回答的。

答案 11 :(得分:0)

我找到了一个非常简单的解决方案。

请先为此库net.sf.json-lib安装。

    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
    }

完成。享受

答案 12 :(得分:0)

import static net.minidev.json.JSONValue.isValidJson;

,然后调用此函数并传递您的JSON字符串:)

答案 13 :(得分: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.");
        }
    }
}

以上解决方案涵盖了两种情况:

  • 重复键
  • 不匹配的引号或缺少括号等。

答案 14 :(得分:0)

恕我直言,最优雅的方法是使用 Java API进行JSON处理 (JSON-P),这是符合 JSR的JavaEE标准之一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();
}

使用Maven,添加对JSON-P的依赖关系:

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

访问the JSON-P official page了解更多信息。

答案 15 :(得分:0)

以下是使用gson库进行严格json解析的有效示例:

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

另请参见我在How to check if JSON is valid in Java using GSON中的其他详细答案,其中包含更多信息和带有各种无效示例的扩展测试用例。

答案 16 :(得分:0)

使用javax.json库的解决方案:

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

答案 17 :(得分:0)

您可以使用Validol声明式验证库中的WellFormedJson类。

声明本身可能如下所示:

new WellFormedJson(
    new Unnamed<>(Either.right(new Present<>(jsonRequestString)))
)

检查阶段如下:

    Result<JsonElement> result =
        (new WellFormedJson(
            new Named<>(
                "vasya",
                Either.right(
                    new Present<>(
                        "{\"guest\":{\"name\":\"Vadim Samokhin\",\"email\":\"samokhinvadim@gmail.com\"},\"source\":1,\"items\":[{\"id\":1900},{\"id\":777}]}"
                    )
                )
            )
        ))
            .result();

    assertTrue(result.isSuccessful());
    assertEquals(
        "{\"guest\":{\"name\":\"Vadim Samokhin\",\"email\":\"samokhinvadim@gmail.com\"},\"source\":1,\"items\":[{\"id\":1900},{\"id\":777}]}",
        result.value().raw().toString()
    );
    assertEquals(
        "{\"name\":\"Vadim Samokhin\",\"email\":\"samokhinvadim@gmail.com\"}",
        result.value().raw().getAsJsonObject().get("guest").toString()
    );

对于这样一个简单的任务,这似乎有些过头了,但是当您必须验证一个复杂的请求时,它就闪耀了。请查看有效的quick start section

答案 18 :(得分:0)

您可以看到,有很多解决方案,它们主要解析JSON以进行检查,最后您必须对其进行解析以确保确定。

但是,根据具体情况,您可以通过预先检查来提高性能。

调用API时,我所做的只是检查第一个字符为“ {”,最后一个字符为“}”。如果不是这种情况,我就不用创建解析器了。

答案 19 :(得分:0)

你可以试试下面的代码,对我有用:

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

 public static JSONObject parseJsonObject(String substring)
 {
  return new JSONObject(new JSONTokener(substring));
 }