这是我的最后一课,读取多个XML文件并在发生读取错误时跳转到下一个文件(感谢Luca的想法)。
我定制ItemReader,从MultiResourceItemReader扩展:
public class MyItemReader extends MultiResourceItemReader<InputElement> {
private SkippableResourceItemReader<InputElement> reader;
public MyItemReader() throws IOException {
super();
// Resources
PathMatchingResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
this.setResources(resourceResolver.getResources("classpath:input/inputFile*.xml"));
// Delegate reader
reader = new SkippableResourceItemReader<InputElement>();
StaxEventItemReader<InputElement> delegateReader = new StaxEventItemReader<InputElement>();
delegateReader.setFragmentRootElementName("inputElement");
Jaxb2Marshaller unmarshaller = new Jaxb2Marshaller();
unmarshaller.setClassesToBeBound(InputElement.class);
delegateReader.setUnmarshaller(unmarshaller);
reader.setDelegate(delegateReader);
this.setDelegate(reader);
}
[...]
@OnReadError
public void onReadError(Exception exception){
reader.setSkipResource(true);
}
}
,并用于跳过当前资源ItemReader,在中间人:
public class SkippableResourceItemReader<T> implements ResourceAwareItemReaderItemStream<T> {
private ResourceAwareItemReaderItemStream<T> delegate;
private boolean skipResource = false;
@Override
public void close() throws ItemStreamException {
delegate.close();
}
@Override
public T read() throws UnexpectedInputException, ParseException, NonTransientResourceException, Exception {
if(skipResource){
skipResource = false;
return null;
}
return delegate.read();
}
@Override
public void setResource(Resource resource) {
skipResource = false;
delegate.setResource(resource);
}
@Override
public void open(ExecutionContext executionContext) throws ItemStreamException {
delegate.open(executionContext);
}
@Override
public void update(ExecutionContext executionContext) throws ItemStreamException {
delegate.update(executionContext);
}
public void setDelegate(ResourceAwareItemReaderItemStream<T> delegate) {
this.delegate = delegate;
}
public void setSkipResource(boolean skipResource) {
this.skipResource = skipResource;
}
}
谢谢!我目前所关心的是找到一种方法来强制MultiResourceItemReader转移到下一个资源。就像我说的,它有一个方法readNextItem,但它是私人的。我觉得我将不得不复制和调整课程。但我不喜欢... – Eria
有了一个听众和一个班级,你可以隔离跳过逻辑,而不需要'复制和修改' –
好的,我在第一次阅读时没有得到你想到的。 您建议在MultiResourceItemReader和读取我的文件的实际委托之间放置一个“假”委托,它返回null以停止读取过程并强制MultiResourceItemReader跳转到下一个资源。我会尝试这样的事情! – Eria