当解组仅包含一个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;
}
我需要一种解组单个目标文件的方法,强制数组有什么意义(在我的用例中不会有)?
答案 0 :(得分:0)
我不明白为什么一定要这么做。
JsonItemReader
被设计为读取an array of objects,因为批处理通常是关于处理包含很多项目而不是单个项目的数据源。
我找不到任何解决方法
JsonObjectReader
是您要寻找的:您可以实现它来读取单个json对象,并将其与JsonItemReader
一起使用(在构造时或使用setter)。这不是解决方法,而是为像您这样的特定用例设计的策略界面。
答案 1 :(得分:0)
这可能不理想,这是我处理情况的方式:
@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));
}
}
答案 2 :(得分:0)
绝对不理想@thomas-escolan。正如@mahmoud-ben-hassine 所指出的,理想的做法是编写自定义阅读器。
如果一些新的 SOF 用户偶然发现了这个问题,我在这里留个 code example on how to do it