1. Overview
1.概述
When working with raw JSON values in Java, sometimes there is a need to check whether it is valid or not. There are several libraries that can help us with this: Gson, JSON API, and Jackson. Each tool has its own advantages and limitations.
在Java中处理原始JSON值时,有时需要检查它是否有效。有几个库可以帮助我们解决这个问题。Gson,JSON API,和Jackson。每个工具都有自己的优势和局限性。
In this tutorial, we’ll implement JSON String validation using each of them and take a closer look at the main differences between the approaches with practical examples.
在本教程中,我们将分别使用它们来实现JSON String验证,并通过实际例子仔细研究这些方法之间的主要区别。
2. Validation with JSON API
2.用JSON API进行验证
The most lightweight and simple library is the JSON API.
最轻巧和简单的库是JSON API。
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.
检查一个String是否是有效的JSON的常见方法是异常处理。因此,我们委托JSON解析,并在值不正确的情况下处理特定类型的错误,或者在没有发生异常的情况下假设值是正确的。
2.1. Maven Dependency
2.1.Maven的依赖性
First of all, we need to include the json dependency in our pom.xml:
首先,我们需要在我们的pom.xml中包含json依赖。
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20211205</version>
</dependency>
2.2. Validating with JSONObject
2.2.用JSONObject进行验证
Firstly, to check if the String is JSON, we will try to create a JSONObject. Further, in case of a non-valid value, we will get a JSONException:
首先,为了检查字符串是否是JSON,我们将尝试创建一个JSONObject。此外,如果一个非有效的值,我们将得到一个JSONException:。
public boolean isValid(String json) {
try {
new JSONObject(json);
} catch (JSONException e) {
return false;
}
return true;
}
Let’s try it with a simple example:
让我们用一个简单的例子来试试。
String json = "{\"email\": \"example@com\", \"name\": \"John\"}";
assertTrue(validator.isValid(json));
String json = "Invalid_Json";
assertFalse(validator.isValid(json));
However, the disadvantage of this approach is that the String can be only an object but not an array using JSONObject.
然而,这种方法的缺点是:String只能是一个对象,而不能使用JSONObject数组。
For instance, let’s see how it works with an array:
例如,让我们看看它是如何与一个数组一起工作的。
String json = "[{\"email\": \"example@com\", \"name\": \"John\"}]";
assertFalse(validator.isValid(json));
2.3. Validating with JSONArray
2.3.用JSONArray进行验证
In order to validate regardless of whether the String is an object or an array, we need to add an additional condition if the JSONObject creation fails. Similarly, the JSONArray will throw a JSONException if the String is not fit for the JSON array as well:
为了验证,无论字符串是一个对象还是一个数组,如果JSONObject创建失败,我们需要添加一个附加条件。类似地,JSONArray将抛出一个JSONException如果String不适合JSON数组也是:<
public boolean isValid(String json) {
try {
new JSONObject(json);
} catch (JSONException e) {
try {
new JSONArray(json);
} catch (JSONException ne) {
return false;
}
}
return true;
}
As a result, we can validate any value:
因此,我们可以验证任何值。
String json = "[{\"email\": \"example@com\", \"name\": \"John\"}]";
assertTrue(validator.isValid(json));
3. Validation with Jackson
3.与Jackson的验证
Similarly, the Jackson library provides a way to validate JSON based on Exception handling. It is a more complex tool with many types of parsing strategies. However, it’s much easier to use.
同样,Jackson库提供了一种基于Exception处理的验证JSON的方法。它是一个更复杂的工具,有许多类型的解析策略。然而,它更容易使用。
3.1. Maven Dependency
3.1.Maven的依赖性
Let’s add the jackson-databind Maven dependency:
我们来添加 jackson-databind Maven依赖。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
</dependency>
3.2. Validating with ObjectMapper
3.2.用ObjectMapper进行验证
We use the readTree() method to read the entire JSON and get a JacksonException if the syntax is incorrect.
我们使用readTree()方法来读取整个JSON,如果语法不正确,会得到一个JacksonException。
In other words, we don’t need to provide additional checks. It works for both objects and arrays:
换句话说,我们不需要提供额外的检查。它对对象和数组都有效。
ObjectMapper mapper = new ObjectMapper();
public boolean isValid(String json) {
try {
mapper.readTree(json);
} catch (JacksonException e) {
return false;
}
return true;
}
Let’s see how we can use this with examples:
让我们通过实例来看看如何使用这个方法。
String json = "{\"email\": \"example@com\", \"name\": \"John\"}";
assertTrue(validator.isValid(json));
String json = "[{\"email\": \"example@com\", \"name\": \"John\"}]";
assertTrue(validator.isValid(json));
String json = "Invalid_Json";
assertFalse(validator.isValid(json));
4. Validation with Gson
4.用Gson进行验证
Gson is another common library that allows us to validate raw JSON values using the same approach. It’s a complex tool that’s used for Java object mapping with different types of JSON handling.
Gson是另一个常见的库,它允许我们用同样的方法来验证原始JSON值。它是一个复杂的工具,用于Java对象映射与不同类型的JSON处理。
4.1. Maven Dependency
4.1.Maven的依赖性
Let’s add the gson Maven dependency:
我们来添加gson Maven依赖。
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
4.2. Non-Strict Validation
4.2.非严格的验证
Gson provides JsonParser to read specified JSON into a tree of JsonElements. Consequently, it guarantees that we get JsonSyntaxException if there’s an error while reading.
Gson提供了JsonParser来读取指定的JSON到一个JsonElements的树。因此,它保证如果在读取时出现错误,我们会得到JsonSyntaxException。
Therefore, we can use the parse() method to compute String and handle Exception in case of a malformed JSON value:
因此,我们可以使用parse()方法来计算String并在出现畸形的JSON值时处理Exception。
public boolean isValid(String json) {
try {
JsonParser.parseString(json);
} catch (JsonSyntaxException e) {
return false;
}
return true;
}
Let’s write some tests to check the main cases:
让我们写一些测试来检查主要情况。
String json = "{\"email\": \"example@com\", \"name\": \"John\"}";
assertTrue(validator.isValid(json));
String json = "[{\"email\": \"example@com\", \"name\": \"John\"}]";
assertTrue(validator.isValid(json));
The main difference of this approach is that the Gson default strategy considers separate string and numeric values to be valid as part of the JsonElement node. In other words, it considers a single string or number as valid as well.
这种方法的主要区别在于,Gson默认策略认为单独的字符串和数字值作为JsonElement节点的一部分是有效的。换句话说,它认为单个字符串或数字也是有效的。。
For example, let’s see how it works with a single string:
例如,让我们看看它如何在一个单一的字符串中工作。
String json = "Invalid_Json";
assertTrue(validator.isValid(json));
However, if we want to consider such values as malformed, we need to enforce a strict type policy on our JsonParser.
然而,如果我们想把这样的值看作是畸形的,我们需要在我们的JsonParser上执行严格的类型策略。
4.3. Strict Validation
4.3.严格的验证
To implement a strict type policy, we create a TypeAdapter and define the JsonElement class as a required type match. As a result, JsonParser will throw a JsonSyntaxException if a type is not a JSON object or array.
为了实现严格的类型策略,我们创建了一个TypeAdapter,并将JsonElement类定义为一个必需的类型匹配。因此,JsonParser 如果一个类型不是JSON对象或数组,将抛出一个JsonSyntaxException。
We can call the fromJson() method to read raw JSON using a specific TypeAdapter:
我们可以调用fromJson()方法,使用特定的TypeAdapter读取原始JSON。
final TypeAdapter<JsonElement> strictAdapter = new Gson().getAdapter(JsonElement.class);
public boolean isValid(String json) {
try {
strictAdapter.fromJson(json);
} catch (JsonSyntaxException | IOException e) {
return false;
}
return true;
}
Finally, we can check whether a JSON is valid:
最后,我们可以检查一个JSON是否有效。
String json = "Invalid_Json";
assertFalse(validator.isValid(json));
5. Conclusion
5.总结
In this article, we’ve seen different ways to check whether a String is valid JSON.
在这篇文章中,我们看到了检查String是否为有效JSON的不同方法。
Each approach has its advantages and limitations. While the JSON API can be used for simple object validation, the Gson can be more extensible for raw value validation as part of a JSON object. However, the Jackson is easier to use. Therefore, we should use the one that fits better.
每种方法都有其优势和局限性。虽然JSON API可用于简单的对象验证,但Gson可作为JSON对象的一部分对原始值验证进行更多扩展。然而,Jackson更容易使用。因此,我们应该使用更适合的那一个。。
Also, we should check if some library is already in use or applies for the rest of the goals as well.
另外,我们应该检查一些库是否已经在使用,或者也适用于其他的目标。
As always, the source code for the examples is available over on GitHub.
像往常一样,这些例子的源代码可以在GitHub上找到。