简体   繁体   English

Spring Boot批处理-MultiResourceItemReader:错误时移至下一个文件

[英]Spring Boot batch - MultiResourceItemReader : move to next file on error

In a batch service, I read multiple XML files using a MultiResourceItemReader, which delegate to a StaxEventItemReader. 在批处理服务中,我使用MultiResourceItemReader读取了多个XML文件,该文件委托给StaxEventItemReader。

If an error is raised reading a file (a parsing exception for example), I would like to specify to Spring to start reading the next matching file. 如果在读取文件时出现错误(例如解析异常),我想指定给Spring开始读取下一个匹配的文件。 Using @OnReadError annotation and/or a SkipPolicy for example. 例如,使用@OnReadError注释和/或SkipPolicy。

Currently, when a reading exception is raised, the batch stops. 当前,当出现读取异常时,该批处理将停止。

Does anyone have an idea how to do it ? 有人知道怎么做吗?

EDIT: I see MultiResourceItemReader has a method readNextItem(), but it's private -_- 编辑:我看到MultiResourceItemReader有一个方法readNextItem(),但它是私有的-_-

I'm not using SB for a while, but looking MultiResourceItemReader code I suppose you can write your own ResourceAwareItemReaderItemStream wrapper where you check for a flag setted to move to next file or to perform a standard read using a delegate. 我有一段时间没有使用SB了,但是我想看一下MultiResourceItemReader代码,我想您可以编写自己的ResourceAwareItemReaderItemStream包装器,在其中检查设置为移至下一个文件或使用委托执行标准读取的标志。
This flag can be stored into execution-context or into your wrapper and should be cleared after a move next. 该标志可以存储在执行上下文中或包装中,并且应在下一步移动后清除。

class MoveNextReader<T> implements ResourceAwareItemReaderItemStream<T> {
  private ResourceAwareItemReaderItemStream delegate;
  private boolean skipThisFile = false;

  public void setSkipThisFile(boolean value) {
    skipThisFile = value;
  }

  public void setResource(Resource resource) {
    skipThisFile = false;
    delegate.setResource(resource);
  }

  public T read() {
    if(skipThisFile) {
      skipThisFile = false;
      // This force MultiResourceItemReader to move to next resource
      return null;
    }
    return delegate.read();
  }
}

Use this class as delegate for MultiResourceItemReader and in @OnReadError inject MoveNextReader and set MoveNextReader.skipThisFile . 使用此类作为MultiResourceItemReader委托,并在@OnReadError注入MoveNextReader并设置MoveNextReader.skipThisFile

I can't test code from myself but I hope this can be a good starting point. 我无法自己测试代码,但我希望这可以成为一个好的起点。

Here are my final classes to read multiple XML files and jump to the next file when a read error occurs on one (thanks to Luca's idea). 这是我的最后一个类,用于读取多个XML文件并在一个文件发生读取错误时跳转到下一个文件(这要归功于Luca的想法)。

My custom ItemReader, extended from MultiResourceItemReader : 我的自定义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 );
    }
}

And the ItemReader-in-the-middle used to skip the current resource : 中间的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;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 春季批处理:具有自定义ItemReader的MultiResourceItemReader无限地读取同一文件 - Spring Batch: MultiResourceItemReader with custom ItemReader reads the same file ad infinitum 在 spring 批处理中,我们如何将处理后的文件移动到另一个文件夹,我正在使用 MultiResourceItemReader 和块处理 - In spring batch how can we move the processed files to another folder, I am using MultiResourceItemReader and chunk processing Spring 引导批处理 MultiResourceItemReader:如何使用 @Value() 从 jar 位置读取文件 - Spring boot batch MultiResourceItemReader: how to read files using @Value() from jar location Spring 使用MultiResourceItemReader 和使用ItemReadListener 批量读取文件 - Spring batch reading files with MultiResourceItemReader and using ItemReadListener Spring批处理MultiResourceItemReader-仅用于合并文件? - Spring batch MultiResourceItemReader - only used for combining files? 每个资源的Spring Batch MultiResourceItemReader块提交 - Spring Batch MultiResourceItemReader Chunk Commit Per Resource 在Spring Batch中解密后通过MultiResourceItemReader读取文件 - Reading Files thru MultiResourceItemReader after de-cryption in Spring Batch 如何使用 spring-batch 和 MultiResourceItemReader 读取文件夹中的所有文件? - How to read all files in a folder with spring-batch and MultiResourceItemReader? Java Spring 批处理 - MultiResourceItemReader 不会在每次作业运行时读取新文件 - Java Spring Batch - MultiResourceItemReader not reading in new files every job run 使用 Spring Boot 和 Spring Batch 读取 .csv 文件并将其存储在数据库中 - Reading .csv file and storing it in a database using Spring Boot and Spring Batch
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM