Перейти к основному содержимому

Проверьте, является ли строка действительной JSON в Java

· 5 мин. чтения

1. Обзор

При работе с необработанными значениями JSON в Java иногда возникает необходимость проверить, допустимы они или нет. В этом нам могут помочь несколько библиотек: Gson , JSON API и Jackson . Каждый инструмент имеет свои преимущества и ограничения.

В этом руководстве мы реализуем проверку строки JSON, используя каждый из них, и более подробно рассмотрим основные различия между подходами на практических примерах.

2. Проверка с помощью JSON API

Самая легкая и простая библиотека — JSON API.

Обычный подход к проверке того, является ли String допустимым JSON, — это обработка исключений. Следовательно, мы делегируем синтаксический анализ JSON и обрабатываем конкретный тип ошибки в случае неправильного значения или предполагаем, что значение правильное, если не произошло исключения .

2.1. Зависимость от Maven

Прежде всего, нам нужно включить зависимость json в наш pom.xml :

<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20211205</version>
</dependency>

2.2. Проверка с помощью JSONObject

Во-первых, чтобы проверить, является ли строка JSON, мы попытаемся создать JSONObject. Далее, в случае невалидного значения, мы получим JSONException:

public boolean isValid(String json) {
try {
new JSONObject(json);
} catch (JSONException e) {
return false;
}
return true;
}

Давайте попробуем это на простом примере:

String json = "{\"email\": \"example@com\", \"name\": \"John\"}";
assertTrue(validator.isValid(json));
String json = "Invalid_Json"; 
assertFalse(validator.isValid(json));

Однако недостатком этого подхода является то, что String может быть только объектом, но не массивом с использованием JSONObject .

Например, давайте посмотрим, как это работает с массивом:

String json = "[{\"email\": \"example@com\", \"name\": \"John\"}]";
assertFalse(validator.isValid(json));

2.3. Проверка с помощью JSONArray

Для проверки независимо от того, является ли String объектом или массивом, нам нужно добавить дополнительное условие, если создание JSONObject не удалось . Точно так же JSONArray выдаст исключение JSONException , если строка также не подходит для массива JSON :

public boolean isValid(String json) {
try {
new JSONObject(json);
} catch (JSONException e) {
try {
new JSONArray(json);
} catch (JSONException ne) {
return false;
}
}
return true;
}

В результате мы можем проверить любое значение:

String json = "[{\"email\": \"example@com\", \"name\": \"John\"}]";
assertTrue(validator.isValid(json));

3. Проверка с Джексоном

Точно так же библиотека Джексона предоставляет способ проверки JSON на основе обработки исключений . Это более сложный инструмент со многими типами стратегий синтаксического анализа. Тем не менее, это намного проще в использовании.

3.1. Зависимость от Maven

Давайте добавим зависимость jackson-databind Maven:

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

3.2. Проверка с помощью ObjectMapper

Мы используем метод readTree() , чтобы прочитать весь JSON и получить исключение JacksonException , если синтаксис неверен.

Другими словами, нам не нужно предоставлять дополнительные проверки. Он работает как для объектов, так и для массивов:

ObjectMapper mapper = new ObjectMapper();

public boolean isValid(String json) {
try {
mapper.readTree(json);
} catch (JacksonException e) {
return false;
}
return true;
}

Давайте посмотрим, как мы можем использовать это на примерах:

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. Проверка с помощью Gson

Gson — еще одна распространенная библиотека, которая позволяет нам проверять необработанные значения JSON, используя тот же подход. Это сложный инструмент, который используется для сопоставления объектов Java с различными типами обработки JSON.

4.1. Зависимость от Maven

Давайте добавим зависимость gson Maven:

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

4.2. Нестрогая проверка

Gson предоставляет JsonParser для чтения указанного JSON в дереве JsonElement s. Следовательно, это гарантирует, что мы получим JsonSyntaxException , если при чтении произойдет ошибка.

Следовательно, мы можем использовать метод parse() для вычисления String и обработки Exception в случае искаженного значения JSON:

public boolean isValid(String json) {
try {
JsonParser.parseString(json);
} catch (JsonSyntaxException e) {
return false;
}
return true;
}

Напишем несколько тестов для проверки основных случаев:

String json = "{\"email\": \"example@com\", \"name\": \"John\"}";
assertTrue(validator.isValid(json));

String json = "[{\"email\": \"example@com\", \"name\": \"John\"}]";
assertTrue(validator.isValid(json));

Основное отличие этого подхода заключается в том, что стандартная стратегия Gson рассматривает отдельные строковые и числовые значения как часть узла JsonElement . Другими словами, он также считает допустимой одну строку или число.

Например, давайте посмотрим, как это работает с одной строкой:

String json = "Invalid_Json";
assertTrue(validator.isValid(json));

Однако, если мы хотим считать такие значения искаженными, нам нужно применить строгую политику типов для нашего JsonParser .

4.3. Строгая проверка

Чтобы реализовать строгую политику типов, мы создаем TypeAdapter и определяем класс JsonElement как соответствие требуемому типу. В результате JsonParser выдаст JsonSyntaxException , если тип не является объектом или массивом JSON.

Мы можем вызвать метод fromJson() для чтения необработанного JSON с использованием определенного TypeAdapter :

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

Наконец, мы можем проверить, действителен ли JSON:

String json = "Invalid_Json";
assertFalse(validator.isValid(json));

5. Вывод

В этой статье мы рассмотрели разные способы проверки того, является ли строка допустимой в формате JSON.

Каждый подход имеет свои преимущества и ограничения. В то время как JSON API можно использовать для простой проверки объектов, Gson может быть более расширяемым для проверки необработанных значений как части объекта JSON. Тем не менее, Джексон проще в использовании. Поэтому мы должны использовать тот, который подходит лучше.

Кроме того, мы должны проверить, не используется ли какая-либо библиотека или применима и для остальных целей.

Как всегда, исходный код примеров доступен на GitHub .