Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring batch 获取OnSkipRead项的路径_Spring Batch - Fatal编程技术网

Spring batch 获取OnSkipRead项的路径

Spring batch 获取OnSkipRead项的路径,spring-batch,Spring Batch,是否有方法获取无法读取的输入文件的位置,以便在SkipListener中使用它 示例: MySkipListener将无法处理或写入的每个文件移动到错误位置: @Override public void onSkipInWrite(MyFileObject arg0, Throwable arg1) { logger.error("onSkipInWrite "); logToErrorDirectory(arg0.getPath(), arg1);

是否有方法获取无法读取的输入文件的位置,以便在
SkipListener
中使用它

示例:

My
SkipListener
将无法处理或写入的每个文件移动到错误位置:

@Override
    public void onSkipInWrite(MyFileObject arg0, Throwable arg1) {
        logger.error("onSkipInWrite ");
        logToErrorDirectory(arg0.getPath(), arg1);

    }

@Override
    public void onSkipInProcess(MyFileObject arg0, Throwable arg1) {
        logger.error("onSkipInProcess ");
        logToErrorDirectory(arg0.getPath(), arg1);

    }

@Override
    public void onSkipInRead(Throwable arg1) {
        // WHAT TO DO HERE

    }
当项目(
.xml
文件)也无法读取时,我需要做同样的事情。

我的配置:

<bean id="ExportPatentReader"
        class="org.springframework.batch.item.file.MultiResourceItemReader"
        scope="step">
        <property name="resources" value="file:SomeFolder/*.xml'</property>
        <property name="delegate" ref="staxPatentReader"></property>
        <property name="strict" value="true"></property>
    </bean>

<bean id="staxPatentReader" class="org.springframework.batch.item.xml.StaxEventItemReader"
        scope="step">
        <property name="fragmentRootElementName" value="Root" />
        <property name="unmarshaller" ref="patentMarshaller" />
    </bean>

    <bean id="patentMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="classesToBeBound">
            <list>
                <value>com.company.MyFileObject</value>
            </list>
        </property>
    </bean>
问题可能是每次提交完成后,
ExecutionContext
都会更新,但找不到解决方法

对于记录期间的更新,打印的步骤执行看起来是这样的:
stepExecution:id=6,version=2,name=partitionedStep:partition4,status=STARTED,exitStatus=EXECUTING,readCount=10,filterCount=0,writeCount=10 readSkipCount=2,writeSkipCount=0,processSkipCount=0,commount=1,backrollcount=0,exitDescription=

所以我认为正确的索引可能是每个提交的
项+MultiResourceReader.index的组合

还有一件事。。。我忘了在开头提到我使用
partitioner
读取文件,尽管不确定这是否会影响结果


我越是使用
SkipListener
,我就越认为更容易的解决方案是编写一个自定义读取器,至少替换
StaxEventReader
:D

MultiResourceItemReader
通过索引跟踪它在
ExecutionContext
中处理的文件。当
资源[]
被注入读卡器时,我们按文件名对数组进行排序。之后,我们在每次更新时将当前文件的索引存储在步骤的
ExecutionContext
中。我想您可以在您的
SkipListener
中实现相同的逻辑。将相同的资源数组注入侦听器,对其进行排序,然后将索引从
ExecutionContext
中拉出。您可以在这里的
MultiResourceItemReader
代码中看到这一点:

我放弃了建议的解决方案,因为我无法让它与提交间隔>1一起工作

解决我问题的肮脏解决方案:

自定义读卡器
以替换
statxeventitemreader
==>

自定义读取器的
read()
中添加了
onSkipInRead()的逻辑


为了解决这个问题,我修改了
read()

    @Override
    public void setResource(Resource arg0) {
        resource = arg0;
        // true for new resource
        ResourceState = true;
    }

    @Override
    public MyFileObject read() throws Exception {
        MyFileObject item = null;
        /*
         * Run only for a new Resource
         */
        if (ResourceState == true) {
            logger.debug("Reading: " + resource.getFileName());

            try {
                // Actual reading
                item = (MyFileObject) unmarshaller.unmarshal(resource.getFile());

            } catch (Exception e) {
                logger.error("Error while reading: " + resource.getFilename());

                logToErrorDirectory(resource, errorPath, e);
            }

            /*
             * Finished reading, resourceState=false
             */
            ResourceState = false;
        }

        return item;
    }

不是很喜欢这个解决方案,但解决了我的问题

这是一个非常有趣的想法,对于commit interval=1非常有效,但对于更大的一个则不行。我更新了我的问题,提供了更多细节
    @Override
    public void setResource(Resource arg0) {
        resource = arg0;
        // true for new resource
        ResourceState = true;
    }

    @Override
    public MyFileObject read() throws Exception {
        MyFileObject item = null;
        /*
         * Run only for a new Resource
         */
        if (ResourceState == true) {
            logger.debug("Reading: " + resource.getFileName());

            try {
                // Actual reading
                item = (MyFileObject) unmarshaller.unmarshal(resource.getFile());

            } catch (Exception e) {
                logger.error("Error while reading: " + resource.getFilename());

                logToErrorDirectory(resource, errorPath, e);
            }

            /*
             * Finished reading, resourceState=false
             */
            ResourceState = false;
        }

        return item;
    }