Выберите любой элемент из схемы JSON при потоковой передаче данных для анализа - PullRequest
0 голосов
/ 30 января 2019

Я пишу десериализатор, который читает огромный файл json и помещает записи, соответствующие фильтру (логика в моем приложении), в базу данных.Файл json имеет фиксированную схему следующим образом:

{
    "cityDetails": {
        "name": "String",
        "pinCodes": "Array of integers ",
        "people": [{
            "name": "String",
            "age": "Integer"
        }]
    }
}

Меня интересует только потоковый список "людей" из файла.Я знаю, что GSON / Jackson предоставляют потоковые API, которые я могу использовать, но я хочу избежать циклического просмотра токенов при их потоковой передаче и сопоставлении их имени, чтобы узнать, заинтересован ли я в них.Я считаю, что должно быть решение, которое может выполнять потоковую передачу в фоновом режиме и направлять / искать поток для интересующего меня токена. Я не вижу никаких причин, почему это не может быть возможным, если я предоставлю свою схему JSON.Есть ли решение для этого?

Вот пример экземпляра моего JSON:

{
    "cityDetails": {
        "name": "mumbai",
        "pinCodes": ["400001", "400002"],
        "people": [{
            "name": "Foo",
            "age": 1
        }, {
            "name": "Bar",
            "age": 2
        }]
    }
}

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Хороший способ сделать это - использовать JsonPath .

Путь json:

$.cityDetails.people

вернет только содержимое массива people:

[
  [
    {
      "name": "Foo",
      "age": 1
    },
    {
      "name": "Bar",
      "age": 2
    }
  ]
]

Здесь - это реализация Java ...

0 голосов
/ 30 января 2019

С GSON я бы просто создал соответствующие DTO для анализируемых данных.

Итак, у вас есть обертка, которая является корневым объектом:

@Getter
public class Wrapper {
    private CityDetails cityDetails; 
}

и подробности города:

@Getter
public class CityDetails {
    private List<Person> people;
}

и, возможно, множество Person с в списке people:

@Getter
@ToString
public class Person {
    private String name;
    private Integer age;
}

Тогда вы можете просто использовать, например, Reader, как показано ниже:

@Test
public void test() {
    Gson gson = new Gson();
    // assuming your json is named "test.json" in the same directory as test
    Reader r = new InputStreamReader(getClass().getResourceAsStream("test.json"));
    Wrapper wrapper = gson.fromJson(r, Wrapper.class);        
    wrapper.getCityDetails().getPeople().forEach(p -> log.info("{}", p.toString()));
}

Gson будет искать и создавать только то, что указано в DTO-классах, остальное игнорируется при разборе.

...