Как проверить, является ли данная строка допустимым JSON в Java


155

Как проверить строку JSON в Java? Или я мог бы разобрать его с помощью регулярных выражений?


попробуйте разбор с gson? проверка с помощью регулярных выражений не может быть хорошей идеей
aishwarya

2
У json.org есть ссылки на очень много парсеров
MartinK

Ответы:


261

Дикая идея, попробуйте разобрать ее и поймать исключение:

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

Этот код использует реализацию JSON API org.json, которая доступна на github , в maven и частично на Android .


2
Это близко, но отсутствует проверка для JSONArray (я обновил этот пост с более подходящей функцией)
Артур

9
Я пробовал строку json, такую ​​как "{'hello': 'foo'} 'invalid'" (добавлено 'invalid' вне {}), и JSONObject не выбрасывает ParseException. Я использую org.json.JSONObject. Это ожидается?
Соичи Хаяси

16
Вы не упомянули библиотеку, в которой есть JSONObject, я не видел ее в стандартной java-
библиотеке

6
Это решение работает в большинстве случаев, но может не работать при определенных обстоятельствах. Например, он допускает запятую перед закрывающей скобкой, что фактически является синтаксической ошибкой. Обратитесь к json.org/javadoc/org/json/JSONObject.html для других угловых случаев.
Hua2308

9
Я не могу понять, почему постеры не могут включать в себя операторы импорта с фрагментами кода. Здесь важно Ответ с вторым рейтингом здесь намного лучше.
seansand

100

JACKSON Библиотека

Одним из вариантов будет использование библиотеки Джексона . Сначала импортируйте последнюю версию (сейчас):

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

Затем вы можете реализовать правильный ответ следующим образом:

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

Пожалуйста, обратите внимание, что может быть «незначительная» проблема из-за запятых, которые будут исправлены в выпуске 3.0.0.


Хотя это работает для больших вещей, таких как несовпадающие кавычки или пропущенные скобки, Gson с радостью проанализирует массив json с запятой, которая не соответствует RFC-4627
эвритмия

@eurythmia Правда! В версии 3.0 они должны решить эту проблему
JeanValjean

1
Это также подтверждает {key: value}, но не является действительным json
Pratapi Hemant Patel

2
new ObjectMapper().readTree("28xjRBuOQqupRopHeSuhRQ")Ловушка ДЖЕКСОНА : анализирует без исключений как IntNode (28). Не очень ожидаемый ...
mgaert

1
Как я понимаю, это решение не только проверяет, но и анализирует (и сохраняет) весь JSON. Он конвертирует числа в Integer / Long / Double и т. Д. Это больше, чем просто проверка синтаксиса, он сохраняет весь JSON в памяти. Это может быть важно для интенсивных нагрузок. Если лучшее решение для проверки синтаксиса существует?
Javapowered

15

С Google Gson вы можете использовать JsonParser:

import com.google.gson.JsonParser;

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

3
Обратите внимание, что это не приводит к ошибке в строках без скобок аля "asdf"
Эндрю

1
Он также не отвергает запятые в массивах JSON.
Сотириос Делиманолис

Я не могу доверять этому ... он говорит, что строка "Сохранить" является разборчивой.
Дерик

Остерегайтесь того примера gson, который использует снисходительный режим анализа, который все еще допускает много отклонений. Смотрите подробности с тестовым примером и примером строгого анализа в других моих ответах.
Вадим

14

Вы можете использовать .mayBeJSON (String str), доступный в библиотеке JSONUtils .


да ... это работает. Спасибо npinti. я пытался с помощью gson, но такого метода я не видел.
Саппу

@sappu: Если этот ответ решил ваш вопрос, пометьте его так. Большинство библиотек, как правило, принимают строку и пытаются ее проанализировать, если при синтаксическом анализе происходит сбой, то есть строка не является допустимой строкой JSON, она выдает исключение.
npinti

@npinti: не удалось для дополнительного}. Возвращает true для неверной строки с дополнительной скобкой =>}
Vivek

3
Этот метод буквально проверяет, что строка начинается и заканчивается либо кавычками, либо скобками. Очень ненадежно.
Майкл Манси

2
вот почему метод называется «может быть», а не «есть» :)
Khoa

5

Это зависит от того, что вы пытаетесь доказать с помощью своей валидации. Конечно, синтаксический анализ json, как и предполагали другие, лучше, чем использование регулярных выражений, потому что грамматика json более сложна, чем это может быть представлено просто регулярными выражениями.

Если json будет когда-либо анализироваться только вашим java-кодом, используйте тот же парсер для проверки.

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

  • многие парсеры игнорируют конечные запятые в объекте или массиве, но старые версии IE могут потерпеть неудачу при попадании запятой в конце.
  • Другие парсеры могут принять запятую, но после нее добавить неопределенную / нулевую запись.
  • Некоторые парсеры могут разрешать имена свойств без кавычек.
  • Некоторые парсеры могут по-разному реагировать на не-ASCII символы в строках.

Если ваша проверка должна быть очень тщательной, вы можете:

  • попробуйте разные парсеры, пока не найдете тот, который не работает во всех угловых случаях, которые я упоминал выше
  • или вы можете запустить jsonlint, используя javax.script. *,
  • или объединить с помощью парсера с запуском jshint используя javax.script. *.

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


Можно ли определить строку как выше? Или это только для идеи.
Сантрон Манибхарати

не возможно, это было из-за моей ошибки. Теперь это исправлено.
Спасибо

1
JSONValidatingReader не является частью Java API
IgorGanapolsky

Пожалуйста , используйте вышеупомянутую библиотеку, спасибо
Джамшир

2

Немного о разборе:

Json и фактически все языки используют грамматику, которая представляет собой набор правил, которые можно использовать в качестве подстановок. чтобы разобрать json, нужно в основном отработать эти замены в обратном порядке

Json - это не зависящая от контекста грамматика , означающая, что вы можете иметь бесконечно вложенные объекты / массивы, и json все равно будет действительным. регулярное выражение обрабатывает только регулярные грамматики (отсюда и название «reg»), которые являются подмножеством контекстно-свободных грамматик, не допускающих бесконечное вложение, поэтому невозможно использовать только regex для анализа всех допустимых json. Вы можете использовать сложный набор регулярных выражений и циклов, предполагая, что никто не будет прятаться, скажем, на 100 уровнях глубиной, но это все равно будет очень сложно.

если вы готовы написать свой собственный синтаксический анализатор,
вы можете создать синтаксический анализатор с рекурсивным спуском после разработки грамматики


2

Проверьте, является ли данная строка допустимым JSON в Kotlin . Я конвертировал ответ MByD Java в Котлин

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

1

Здесь вы можете найти инструмент, который может проверять файл JSON, или вы можете просто десериализовать ваш файл JSON с любой библиотекой JSON, и если операция прошла успешно, она должна быть действительной (например, google-json, которая выдаст исключение, если ввод это разбор недействительный JSON).


1

Используя Playframework 2.6, библиотека Json, найденная в Java-API, также может быть использована для простого анализа строки. Строка может быть элементом 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;
        }
    }

1

ИМХО, самый элегантный способ - использовать Java API для JSON Processing (JSON-P), один из стандартов JavaEE, который соответствует 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();
}

Используя Maven, добавьте зависимость от JSON-P:

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

Посетите официальную страницу JSON-P для получения дополнительной информации.


1

Вот рабочий пример для строгого разбора json с библиотекой gson :

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

См. Также мой другой подробный ответ в разделе Как проверить, является ли JSON действительным в Java, используя GSON с дополнительной информацией и расширенным контрольным примером с различными недопустимыми примерами.


1

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

Но, в зависимости от контекста, вы можете улучшить производительность с предварительной проверкой.

Когда я вызываю API, я просто проверяю, что первый символ - «{», а последний - «}». Если это не так, я не буду создавать парсер.


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
    }

Готово. наслаждаться


0

Ответы частично верны. Я тоже столкнулся с той же проблемой. Разбор json и проверка на исключение кажется обычным способом, но решение для ввода json не удается, что-то вроде

{"outputValueSchemaFormat": "", "sortByIndexInRecord": 0, "sortOrder": 847874874387209 "по убыванию"} kajhfsadkjh

Как вы можете видеть, JSON является недопустимым, так как есть конечные символы мусора. Но если вы попытаетесь проанализировать вышеупомянутый json с помощью jackson или gson, вы получите проанализированную карту действительных json, а завершающие символы мусора игнорируются. Что не является обязательным решением, когда вы используете парсер для проверки валидности json.

Для решения этой проблемы смотрите здесь .

PS: на этот вопрос я отвечал и отвечал.


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

а затем вызовите эту функцию, передавая строку JSON :)


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.");
        }
    }
}

Приведенное выше решение охватывает оба сценария:

  • дубликат ключа
  • несоответствующие кавычки или пропущенные скобки и т. д.

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

0

Вы можете использовать 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()
    );

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.