解组仅包含单个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;
}
我需要一种解组单个目标文件的方法,强制数组的重点是什么(在我的用例中我没有)?
我不明白为什么必须如此。
JsonItemReader
旨在读取an array of objects,因为批处理通常是关于处理包含大量项目的数据源,而不是单个项目。
我找不到任何解决方法
JsonObjectReader
正是您所寻找的:您可以实现它来读取单个json对象并将其与JsonItemReader
一起使用(在构造时或使用setter)。这不是一种解决方法,而是针对像您这样的特定用例设计的策略界面。
认为这可能不太理想,这就是我如何处理这种情况:
@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));
}
}