Unmarshalling с Джексоном «Входной поток Json должен начинаться с массива объектов Json» - PullRequest
0 голосов
/ 22 апреля 2019

Я получаю сообщение об ошибке при отмене сортировки файлов, которые содержат только один объект JSON: «IllegalStateException: входной поток Json должен начинаться с массива объектов Json». Я не могу найти никакого обходного пути и не понимаю, почемуэто должно быть так.

@Bean
public ItemReader<JsonHar> reader(@Value("file:${json.resources.path}/*.json") Resource[] resources) {
    log.info("Processing JSON resources: {}", Arrays.toString(resources));
    JsonItemReader<JsonHar> delegate = new JsonItemReaderBuilder<JsonHar>()
            .jsonObjectReader(new JacksonJsonObjectReader<>(JsonHar.class))
            .resource(resources[0])  //FIXME had to force this, but fails anyway because the file is "{...}" and not "[...]"
            .name("jsonItemReader")
            .build();
    MultiResourceItemReader<JsonHar> reader = new MultiResourceItemReader<>();
    reader.setDelegate(delegate);
    reader.setResources(resources);
    return reader;
}

Мне нужен способ разбить отдельные объектные файлы, какой смысл в форсировании массивов (которого у меня не будет в моем случае использования) ??

Ответы [ 2 ]

0 голосов
/ 25 апреля 2019

Думал, что это не может быть идеальным, вот как я справился с ситуацией:

@Bean
public ItemReader<JsonHar> reader(@Value("file:${json.resources.path}/*.json") Resource[] resources) {
    log.info("Processing JSON resources: {}", Arrays.toString(resources));
    JsonItemReader<JsonHar> delegate = new JsonItemReaderBuilder<JsonHar>()
            .jsonObjectReader(new JacksonJsonObjectReader<>(JsonHar.class))
            .resource(resources[0]) //DEBUG had to force this because of NPE...
            .name("jsonItemReader")
            .build();
    MultiResourceItemReader<JsonHar> reader = new MultiResourceItemReader<>();
    reader.setDelegate(delegate);
    reader.setResources(Arrays.stream(resources)
            .map(WrappedResource::new) // forcing the bride to look good enough
            .toArray(Resource[]::new));
    return reader;
}
@RequiredArgsConstructor
static class WrappedResource implements Resource {
    @Delegate(excludes = InputStreamSource.class)
    private final Resource resource;
    @Override
    public InputStream getInputStream() throws IOException {
        log.info("Wrapping resource: {}", resource.getFilename());
        InputStream in = resource.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in, UTF_8));
        String wrap = reader.lines().collect(Collectors.joining())
                .replaceAll("[^\\x00-\\xFF]", "");  // strips off all non-ASCII characters
        return new ByteArrayInputStream(("[" + wrap + "]").getBytes(UTF_8));
    }
}
0 голосов
/ 23 апреля 2019

Я не понимаю, почему так должно быть.

JsonItemReader предназначен для чтения массива объектов , поскольку пакетная обработка обычно заключается в обработке источников данных с большим количеством элементов, а не с одним элементом.

Я не могу найти обходного пути

JsonObjectReader - это то, что вы ищете: вы можете реализовать его для чтения одного объекта json и использовать его с JsonItemReader (либо во время создания, либо с помощью установщика). Это не обходной путь, а интерфейс стратегии, разработанный для конкретных случаев использования, подобных вашему.

...