Java получает определенные данные из динамического JSONObject

У меня есть строка JSON, и я конвертирую ее в JSONObject.

Я хочу получить определенные данные из JSONObject, и каждый раз, когда JSONObject меняет свою структуру, иногда он находится в массиве внутри JSON, а иногда нет. пример: в первый раз JSON приходит вот так

{
  "id": "1",
  "Name": "Jack",
  "Value": {
    "data": [
      {"time": "2023", "age": "22"}
    ]
}}

второй раз

{ 
  "age": "22",
  "time": "2023",
  "Value": {
    "data": [
      {"Name": "Jack", "id": "1" }
    ]
}}

если я хочу получить имя в первом JSON

jsonObject.getString("Name")

а для второго я бы использовал

jsonObject.getJSONArray("data").getJSONObject(0).getString("Name")

есть ли способ получить значение динамически независимо от того, где находятся ключи?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
52
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Если ваш API исходит от другой команды или внешнего поставщика, первое, что я бы посоветовал вам, — это четко определить контракт. В противном случае вы можете использовать метод isNull(String key) из JSONObject, чтобы проверить, существует ли ключ или нет.

Пример здесь:

JSONObject jsonObject = new JSONObject(YOUR_JSON_STRING);
String nameValue;

if (jsonObject.isNull("Name")) {
    nameValue = jsonObject.getJSONObject("Value")
                .getJSONArray("data")
                .getJSONObject(0)
                .getString("Name");
} else {
    nameValue = jsonObject.getString("Name");
}

System.out.println(nameValue);

спасибо, это помогло мне проверить значения.

Mhamad Abu AlGhanam 15.01.2023 09:39

Если строки JSON всегда одинаковы, вы можете попробовать небольшой метод синтаксического анализатора, как показано ниже. Он возвращает карту ключ/значение (строка/объект):

public static java.util.Map<String, Object> mapJsonObject(String jsonString) {
    String json = jsonString
            .replaceAll("(?i)[\\[\\]\\{\\}\"]|\"?value\"?:|\"?data\"?:|\n?", "")
            .replaceAll("\\s+", " ");
    String[] keyValueParts = json.split("\\s*,\\s*");
    java.util.Map<String, Object> map = new java.util.HashMap<>();
    for (String str : keyValueParts) {
        String[] pts = str.split("\\s*:\\s*");
        map.put(pts[0].trim(), pts[1]);
    }
    return map;
}

Использовать:

String jsonString = "{\n"
            + "  \"id\": \"1\",\n"
            + "  \"Name\": \"Jack\",\n"
            + "  \"Value\": {\n"
            + "    \"data\": [\n"
            + "      {\"time\": \"2023\", \"age\": \"22\"}\n"
            + "    ]\n"
            + "}}";

java.util.Map<String, Object> map = mapJsonObject(jsonString);
System.out.println(map);

В окне консоли появится:

{id=1, time=2023, age=22 , Name=Jack}

Вы можете рассмотреть библиотеку Josson.

https://github.com/octomix/josson

Десериализация

Josson josson1 = Josson.fromJsonString(
    "{" +
    "  \"id\": \"1\"," +
    "  \"Name\": \"Jack\"," +
    "  \"Value\": {" +
    "    \"data\": [" +
    "      {\"time\": \"2023\", \"age\": \"22\"}" +
    "    ]" +
    "  }" +
    "}");

Josson josson2 = Josson.fromJsonString(
    "{ " +
    "  \"age\": \"22\"," +
    "  \"time\": \"2023\"," +
    "  \"Value\": {" +
    "    \"data\": [" +
    "      {\"Name\": \"Jack\", \"id\": \"1\" }" +
    "    ]" +
    "  }" +
    "}");

Запрос

*() — это многоуровневый поиск по подстановочным знакам. Он возвращает первый разрешимый элемент.

System.out.println(josson1.getString("coalesce(Name, *().Name)"));
// Output: Jack

System.out.println(josson2.getString("coalesce(Name, *().Name)"));
// Output: ["Jack"]
// It is because "Name" is inside array "data".

System.out.println(josson1.getString("coalesce(Name, *().Name).first()"));
// Output: Jack

System.out.println(josson2.getString("coalesce(Name, *().Name).first()"));
// Output: Jack
// Added function first() to extract the value.

спасибо, я сделал ручной поиск на разных уровнях, попробую в следующий раз.

Mhamad Abu AlGhanam 15.01.2023 09:37

Другие вопросы по теме