Spring Batch如何在处理器中同时处理多个记录?

Spring Batch如何在处理器中同时处理多个记录?,spring,spring-batch,Spring,Spring Batch,我有一个文件来解析和处理记录。它可以一行一行地工作(一次解析一条记录)。我的要求是我必须通过多行解析并从每个记录中获取所需的信息,然后在组合从所有记录中获取的信息之后,我调用一个服务来执行业务逻辑。我必须在我的处理器类中执行这个逻辑。数据如下例所示: 001 123456 987654321551580韦恩博士1 001 123456 987654321552零件786 1 001 123456 987654321553洛杉矶1 001 123456 987654321554CA 1 001 1

我有一个文件来解析和处理记录。它可以一行一行地工作(一次解析一条记录)。我的要求是我必须通过多行解析并从每个记录中获取所需的信息,然后在组合从所有记录中获取的信息之后,我调用一个服务来执行业务逻辑。我必须在我的处理器类中执行这个逻辑。数据如下例所示:

001 123456 987654321551580韦恩博士1

001 123456 987654321552零件786 1

001 123456 987654321553洛杉矶1

001 123456 987654321554CA 1

001 123456 987654321555900001 1

第30-32列中可用的数据元素是我感兴趣的从每条记录中获取的数据元素。在上述示例中,每行中的值分别为551、552、553、554、555。他们都在档案里。因此,基本上,当处理器中的当前项解析第一行并发现其“551”(在业务代码中表示地址行1)时,我希望获取该行后面的其余地址,并将它们保存在一个完整的地址中。最后,我想将这个地址从处理器传递给服务类,然后继续解析文件中的下一条可用记录。我的问题是,处理器对每条记录逐行工作,因此,这样我就无法跟踪/关联所有这些相关行。
对不起,如果我不能用更简单的方式解释我的问题..我是Spring Batch的新手,还在学习

如果您知道关联的数据记录将在文件中彼此相邻(而不是随机分布),则可以利用
singleItemPeakableItemReader
关联多行以创建一个完整的对象。这有更多的信息

示例上下文文件:

<bean id="peekingReader" class="com.package.whatever.YourPeekingReader">
    <property name="delegate" ref="flatFileItemReader"/>
</bean>

<bean id="flatFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="resource" value="file://temp/file.txt" />
    <property name="lineMapper">
        <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
            <property name="lineTokenizer" ref="yourTokenizer"/>
            <property name="fieldSetMapper" ref="yourMapper"/>
        </bean>
    </property>
</bean>
public class YourPeekingReader extends SingleItemPeekableItemReader<YourObject> {

    @Override
    public YourObject read() {

        YourObject item = super.read();

        if (item == null) {
            return null;
        }

        while (true) {
            YourObject possibleRelatedObject = peek();
            if (possibleRelatedObject == null) {
                return item;
            }

            //logic to determine if next line in file relates to same object
            boolean matches = false; 

            if (matches) {
                item.addRelatedInfo(super.read());
            } else {
                return item;
            }
        }


    }

}

偷窥阅读器示例:

<bean id="peekingReader" class="com.package.whatever.YourPeekingReader">
    <property name="delegate" ref="flatFileItemReader"/>
</bean>

<bean id="flatFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="resource" value="file://temp/file.txt" />
    <property name="lineMapper">
        <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
            <property name="lineTokenizer" ref="yourTokenizer"/>
            <property name="fieldSetMapper" ref="yourMapper"/>
        </bean>
    </property>
</bean>
public class YourPeekingReader extends SingleItemPeekableItemReader<YourObject> {

    @Override
    public YourObject read() {

        YourObject item = super.read();

        if (item == null) {
            return null;
        }

        while (true) {
            YourObject possibleRelatedObject = peek();
            if (possibleRelatedObject == null) {
                return item;
            }

            //logic to determine if next line in file relates to same object
            boolean matches = false; 

            if (matches) {
                item.addRelatedInfo(super.read());
            } else {
                return item;
            }
        }


    }

}
public类YourPeekingReader扩展了SingleItemPeekableItemReader{
@凌驾
公共对象读取(){
YourObject item=super.read();
如果(项==null){
返回null;
}
while(true){
YourObject-possibleRelatedObject=peek();
if(possibleRelatedObject==null){
退货项目;
}
//确定文件中的下一行是否与同一对象相关的逻辑
布尔匹配=假;
如果(匹配){
item.addRelatedInfo(super.read());
}否则{
退货项目;
}
}
}
}

@Dean.再次感谢。更准确地说,我的代码是这样的

Customer-record-reader.xml

<batch:job id="myFileReaderJob">
    <batch:step id="stepA" next="stepSuccess">
        <batch:tasklet>        
        <batch:chunk reader="myInputReader" processor="myProcessor" writer="myWriter" commit-interval="1"/>
        </batch:tasklet>
    </batch:step>
    <batch:step id="stepSuccess">
        <batch:tasklet ref="successTasklet" />
    </batch:step>
</batch:job>

<bean id="myInputReader" scope="step" class="org.springframework.batch.item.file.FlatFileItemReader">
        <property name="lineMapper" ref="myLineMapper" />
</bean>

<bean id="myLineMapper" class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean id="fixedLengthLineTokenizer" class="org.springframework.batch.item.file.transform.FixedLengthTokenizer">
        <property name="names" value="custRecord,tranId,partyId,uniquePartyId,deNum,deVal" />
        <property name="columns" value="1-75,1-3,6-11,21-29,30-32,33-62" />
        <property name="strict" value="false" />
    </bean>
</property>
<property name="fieldSetMapper">
    <bean       class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
        <property name="prototypeBeanName" value="myInputData" />
    </bean>
</property>
</bean>

如您所见,我没有使用ItemReader的自定义实现来包装FlatFileItemReader。您能否更详细地阐述一下如何在上面的代码中进行更改以实现SingleItemPeakableItemReader

谢谢

@Dean
我试着按照你的建议去实施
Config1.xml
我的mainConfig.xml文件更改:
创建了一个新的Reader类:
公共类ParticipatRecordT813ItemReader扩展了SingleItemPeakableItemReader{
私有静态最终字符串CLASS=“ParticipantRecordT813ItemReader”;
@凌驾
public ParticipantRecordT813InputData read()引发意外的InputException、ParseException、Exception{
ParticipantRecordT813InputData项=super.read();
报告(类,“我在读者中:”;
如果(项!=null){
而(item.getDeNum()=“551”){
report(类,“我在读卡器中,位于DE551::”+item.getDeNum());
ParticipantRecordT813InputData可能RelatedObject=peek();
if(possibleRelatedObject==null){
退货项目;
}
//确定文件中的下一行是否与同一对象相关的逻辑
布尔匹配=possibleRelatedObject.getDeNum()=“552”;
如果(匹配){
report(类,“我在读卡器中,位于DE552::”+possibleRelatedObject.getDeNum());
}否则{
退货项目;
}
}
}
退货项目;
}
}
我得到以下例外情况:
错误[main](AbstractStep.java:225)-在作业prT813FileReaderJob中执行步骤B时遇到错误
org.springframework.beans.factory.BeanCreationException:创建URL[]中定义的名为“scopedTarget.prT813MultiReader”的bean时出错:bean初始化失败;嵌套异常为org.springframework.beans.ConversionNotSupportedException:未能转换类型为'com.sun.proxy.$Proxy10实现org.springframework.batch.item.StreamReader、org.springframework.batch.item.peakableItemReader、java.io.Serializable、org.springframework.aop.scope.ScopedObject、,org.springframework.aop.framework.AopInfrastructureBean、org.springframework.aop.SpringProxy、org.springframework.aop.framework.Advised“to required type”org.springframework.batch.item.file.ResourceAwareItemReaderItemStream”作为属性“delegate”;嵌套异常为java.lang.IllegalStateException:无法转换[com.sun.proxy]类型的值