Разбор вложенных JSON в Java - PullRequest
1 голос
/ 14 июля 2020

У меня странная JSON, которая выглядит так

[
  [
    {
      "id": "1",
      "clientId": "user"
    },
    {
      "id": "2",
      "clientId": "user"
    } 
 ],
  [
    {
      "Status": "NotCompleted",
      "StatusId": 0
    },
    {
      "Status": "Importing",
      "StatusId": 10
    }
  ]
]

Я пытаюсь разобрать ее с помощью Gson или JsonParser.

Классы выглядят так

public class Event {
    public String id;
    public String clientId;
}

public class Status {
    public String Status;
    public String StatusId;
}

public class AllEvents {

public Event[] events;
public Status[] statuses;
}

Но когда я пытаюсь разобрать его с помощью Gson (например)

  AllEvents[] r = new Gson().fromJson(response, AllEvents[].class);

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 6 path $[0]

Не могли бы вы помочь мне с разбором такой модели? Не могу найти, что делаю неправильно в этом случае.

Заранее спасибо

Ответы [ 3 ]

1 голос
/ 14 июля 2020

Для решения такой проблемы существует два подхода:

Первый подход: Измените JSON содержимое файла (allEvents) на:

[
  {
    "events": [
      {
        "id": "1",
        "clientId": "user"
      },
      {
        "id": "2",
        "clientId": "user"
      }
    ],
    "statuses": [
      {
        "Status": "NotCompleted",
        "StatusId": 0
      },
      {
        "Status": "Importing",
        "StatusId": 10
      }
    ]
  }
]

и после этого ваш код будет работать отлично.

Второй подход:

вам нужно ввести код в соответствии с приведенным выше совпадением JSON структура:

Пожалуйста найдите ниже код, который вам поможет.

    Gson gson = new Gson();
    Object[] r = gson.fromJson(loadDataAsString(), Object[].class);
    AllEvents allEvents = new AllEvents();
    //if your json structure position is fixed the do this commented code
    //allEvents.events = gson.fromJson(gson.toJson(r[0]), Event[].class); //if your json Event structure position is fixed at 0 index
    //allEvents.statuses = gson.fromJson(gson.toJson(r[1]), Status[].class); //if your json Status structure position is fixed at 1 index
    //if your json structure position is not fixed the do below code
    allEvents.events = Arrays.stream(r)
            .flatMap(x -> Arrays.stream(gson.fromJson(gson.toJson(x), Event[].class)))
            .filter(y -> y.id != null).toArray(Event[]::new);//id as primary key
    allEvents.statuses = Arrays.stream(r)
            .flatMap(x -> Arrays.stream(gson.fromJson(gson.toJson(x), Status[].class)))
            .filter(y -> y.Status != null).toArray(Status[]::new);//Status as primary key
    System.out.println(gson.toJson(allEvents));//{"events":[{"id":"1","clientId":"user"},{"id":"2","clientId":"user"}],"statuses":[{"Status":"NotCompleted","StatusId":"0.0"},{"Status":"Importing","StatusId":"10.0"}]}
0 голосов
/ 14 июля 2020

Решена проблема таким образом:

org.json.JSONArray allEvents = new org.json.JSONArray(response.getBodyAsString());

В результате я получил JSONArray с 2 элементами. Затем извлекли необходимое значение через

allEvents.getJSONArray(0)

И затем сопоставили предыдущим способом с помощью jackson ObjectMapper.

Спасибо за ответы!

0 голосов
/ 14 июля 2020

Вместо этого используйте JsonReader. Итак, если вы знаете, что json начинается с [и заканчивается], используйте read с beginArray. Ваш in - InputStream, это может быть файл, поток сокета или строковый поток.

     JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
     List<YourMessage> messages = new ArrayList<YourMessage>();

     reader.beginArray();
     while (reader.hasNext()) {
        messages.add (do something with reader);//<-- that is pseudo code
     }
     reader.endArray();
     return messages;

Для получения более подробной информации проверьте эту ссылку https://www.javadoc.io/doc/com.google.code.gson/gson/2.8.0/com/google/gson/stream/JsonReader.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...