Java中可靠的JSON字符串验证器

10

我需要一种可靠的JSON字符串验证器-一种方法,可以传入一个字符串并检查它是否是有效的JSON。例如:如果我传递{"color":"red"}{"amount":15},它将通过,但像"My invalid json"这样的内容则不会。简而言之,我需要像www.jsonlint.com验证器一样可靠的东西。顺便说一句- 我对反序列化成Java对象没有兴趣,因为那不是我的要求。我可能会收到任意字符串,所有我需要做的就是验证它是否具有有效的JSON格式。

我已经在这个论坛上研究了关于Java JSON字符串验证的几篇帖子。

目前我所做的:

我尝试使用以下方式中的类:org.json.JSONObjectorg.json.JSONArray

private static boolean isValidJSONStringObject(String requestBody){
    try {
        new JSONObject(requestBody);
    } catch (JSONException jsonEx) {
        return false;
    }
    return true;
}

private static boolean isValidJSONStringArray(String requestBody) {
    try {
        new JSONArray(requestBody);
    } catch (JSONException jsonEx) {
        return false;
    }
    return true;
}

但是,以下字符串(整行)仍然可以通过,但它们不应该:

{"color":"red"}{"var":"value"}

[1,2,3][true,false]

换句话说,当我在某个父对象中没有任何封装的情况下重复使用对象/数组时。如果您将这些行粘贴到www.jsonlint.com验证器中,则两者都会失败。

我知道总是有正则表达式选项,但我想不能保证100%,因为JSON的递归性质以及那些正则表达式会变得非常复杂。

非常感谢任何帮助!


你尝试过其他的库吗?例如,我认为jackson不允许那样做。 - yshavit
1
"My invalid json" 是一个无效JSON的坏例子,因为它实际上是一个有效的JSON字符串。 - pfyod
3个回答

6
Gson可以处理此问题。以下是一个示例:
public boolean isValid(String json) {
    try {
        new JsonParser().parse(json);
        return true;
    } catch (JsonSyntaxException jse) {
        return false;
    }
}

String json = "{\"color\":\"red\"}{\"var\":\"value\"}";
System.out.println(isValid(json));

请注意,Gson允许一些JSON输入的宽松性,这可能不是期望的。例如,解析器会自动将未引用的键转换为引用的键。根据您的预期使用方式,这可能或可能不是一个决定性问题。

1
Jackson库似乎无法处理此问题,除非您知道要反序列化的对象类型。这个Gson库更好,但似乎有点宽松。例如,它将abc转换为"abc"而不是抛出错误。但是,如果您将可接受的内容限制为.isJsonObject()JsonElement的方法),那么它就可以很好地工作。 - Allan
1
@Allan - Jackson可以使用其中一个readTree方法解析没有结束对象类型的JSON。但是它默认情况下不会可靠地报告无效的JSON。Gson的宽容模式在某些方面是软性的,最新的所谓错误修复显然没有保持。感谢您的反馈,我已更新我的答案。 - Perception
是的,考虑到gson解析器的“软宽容模式”,我们决定(目前)补充使用jackson解析器以满足我们所有的需求。 - rich

3

现在我们的解决方案是使用两个不同的库(第一个是私有方法gson,第二个是私有方法jackson),这并不理想,但至少我们通过了所有的单元测试和集成测试。我敢打赌我们能够只使用jackson工具来完成我们需要的所有功能。

public static boolean isStringValidJSON(String jsonString) {
    return (isJSONStringObjectOrArray(jsonString) && isJSONStringParsable(jsonString));
}

private static boolean isJSONStringObjectOrArray(String jsonString) {
    try {
        JsonElement element = new JsonParser().parse(jsonString);

        return (element.isJsonObject() || element.isJsonArray());
    } catch (JsonSyntaxException jsonEx) {
        return false;
    }
}

private static boolean isJSONStringParsable(String jsonString) {
    try {
        org.codehaus.jackson.JsonParser parser = 
          new ObjectMapper().getJsonFactory().createJsonParser(jsonString);
        while(parser.nextToken() != null) {
        }
        return true;
    } catch (JsonParseException e) {
        return false;
    } catch (IOException e) {
        return false;
    }
}

-3

将您的字符串粘贴到这里。查看输出。

编辑:

上面的链接不再有效,这个是一个很好的替代方案。


3
楼主想通过编程来完成这个任务,而不是使用工具。 - SMR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接