java - Spring 批问题

标签 java spring spring-batch

我在我的项目中有要求,我想在固定长度的文件中处理数据。一个数据文件包含一个标题行和许多详细信息行。标题行包含详细信息行的汇总和合并信息。例如报告期、报告雇主、总金额等。详细信息行包含每个员工的信息。例如员工缴费、缴费期限等。工作中会收到很多来自不同雇主的数据文件,需要处理这些文件。

因此,我创建了一个包含以下读者和作者以及其他自定义类的一步工作 A。 MultiResourceItemReade 读取文件夹中的所有文件。 b. FlatFileItemReader 读取每个文件。从 MultiResourceItemReader 委托(delegate)。 C。我跳过第一行并处理 LineCallbackHandler d.我能够解析标题行并将其转换为 Report 对象。 e.我正在使用 DefaultLineMapper 和 BeanWrapperFieldSetMapper 来解析详细信息行并转换为 MemberRecrod 对象。

我需要帮助来使用 spring batch 实现以下目标。

  1. 我希望在 ItemWriter 中为文件夹中处理的每个文件提供一个 Report 对象。这样我就可以将所有 MemberRecord 对象 [详细信息行] 添加到 Report 对象并将其保存到数据库 [我正在为 ORM 使用 hibernate 模式]。我试图通过将 Report 对象添加到 JobExecutionContext 并在 ItemWriter 中访问它来做到这一点。所以我从 MemberRecordHeaderLineHandler 类扩展了 StepExecutionListenerSupport [这实现了 LineCallbackHandler]。并覆盖 beforeStep 方法。我能够在 beforeStep 方法中获取 JobExection 对象,并将 JobExection 对象存储到 MemberRecordHeaderLineHandler 类中的局部变量中。但是当控制转到 handleLine 方法时,JobExection 变量为空。我正在解析标题行并将其转换为 handleLine 方法中的 Report 对象。由于 JobExection 为空,我无法将 Rerpot 对象添加到 JobExecutionContext 对象。我不确定如何将 Report 对象传递给 ItemWriter。请告诉我如何从 LineCallBackHandler 到 ItemWriter 的值。

我还需要有关如何使用 Spring Batch 实现以下功能的建议。

  1. 目前我的示例数据文件位于 webinf/conf/data 文件夹下的一个文件夹中。理想情况下,我想处理来自 FTP 位置的所有文件。如何为资源属性指定 FTP 文件夹位置。
  2. 成功处理每个文件后,我需要将文件存档到不同的文件夹中。如何使用 Spring Batch 归档文件。
  3. 如果由于错误的数据格式导致任何异常,我需要更新数据库中的记录并将出错的文件移动到错误文件夹。我不希望由于此错误而停止作业。我想继续处理其他文件。在这种情况下我该如何处理异常。

作业 xml 文件。

    <bean id="erLoadFolderReader" class="org.springframework.batch.item.file.MultiResourceItemReader" scope="step">
        <property name="resources" value="#{jobParameters['FILE_NAME']}" />
        <property name="delegate" ref="erLoadFileReader" />
        <property name="saveState" value="false" />
    </bean>

    <bean id ="memberRecordHeaderLineHandler" class="com.htcinc.rs.batch.infrastructure.erLoadJob.MemberRecordHeaderLineHandler" />
    <bean id="erLoadFileReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
        <property name="saveState" value="false" />
        <property name="resource" value="#{jobParameters['FILE_NAME']}"  /> 
        <property name="linesToSkip" value="1" />
        <property name="skippedLinesCallback">
            <bean class="com.htcinc.rs.batch.infrastructure.erLoadJob.MemberRecordHeaderLineHandler">
                <property name="wcReportService" ref="wcReportService" />
                <property name="names" value="empNo,planCode,startDate,endDate,totalEmprContrb,totalEmplContrb,reportType" />
                <property name="headerTokenizer">
                    <bean class="org.springframework.batch.item.file.transform.FixedLengthTokenizer">
                        <property name="names" value="organizationCode,planCode,beginDate,endDate,totalEmployerContribution,totaEmployeeContribution,reportingType"></property>
                        <property name="columns" value="1-9,10-17,18-25,26-33,34-48,49-63,64-67" />
                    </bean>
                </property>
            </bean>
        </property>
        <property name="lineMapper">
            <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
                <property name="lineTokenizer">
                    <bean class="org.springframework.batch.item.file.transform.FixedLengthTokenizer">
                        <property name="names" value="ssn,firstName,lastName,middleName,birthDateText,genderCode,addressStartDateText,addrLine1,addrLine2,addrLine3,city,state,zip,zipPlus,wagesText,employerContributionText,employeeContributionText,recordType,startDateText,endDateText,serviceCreditDaysText,serviceCreditHoursText,jobClassCode,positionChangeDateText,hireDateText,terminationDateText,notes" />
                        <property name="columns" value="1-9,10-29,30-59,60-79,80-87,88-88,89-96,97-126,127-146,147-166,167-181,182-183,184-188,189-192,193-205,206-214,215-223,224-227,228-235,236-243,244-246,247-251,252-255,256-263,264-271,272-279,280-479" />
                    </bean>
                </property>
                <property name="fieldSetMapper">
                    <bean
                        class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
                        <property name="targetType"
                            value="com.htcinc.rs.domain.batch.MemberRecord" />
                    </bean>
                </property>
            </bean>
        </property>
    </bean>
    <bean id="memberRecordItemWriter" class="com.htcinc.rs.batch.infrastructure.erLoadJob.MemberRecordItemWriter" />
    <bean id="memberRecordItemProcessor" class="com.htcinc.rs.batch.infrastructure.erLoadJob.MemberRecordItemProcessor" />

    <batch:job id="erLoadJob">
        <batch:step id="erLoadJob_step1">
            <batch:tasklet>
                <batch:chunk reader="erLoadFolderReader" writer="memberRecordItemWriter" processor="memberRecordItemProcessor" commit-interval="1" />
            </batch:tasklet>
            <batch:listeners>
                <batch:listener ref="memberRecordHeaderLineHandler"/>
            </batch:listeners>          
        </batch:step>
    </batch:job>
</beans>

MemberRecordHeaderLineHandler.Java 文件

    private WCReportServiceDefaultImpl wcReportService;
    private WCReport wcReport;
    private JobExecution jobExecution;
    private LineTokenizer headerTokenizer;
    private String names;

    public WCReportServiceDefaultImpl getWcReportService() {
        return wcReportService;
    }

    public void setWcReportService(WCReportServiceDefaultImpl wcReportService) {
        this.wcReportService = wcReportService;
    }

    public LineTokenizer getHeaderTokenizer() {
        return headerTokenizer;
    }

    public void setHeaderTokenizer(LineTokenizer headerTokenizer) {
        this.headerTokenizer = headerTokenizer;
    }

    public String getNames() {
        return names;
    }

    public void setNames(String names) {
        this.names = names;
    }

    @Override
    public void handleLine(String headerLine) {
        FieldSet fs = getHeaderTokenizer().tokenize(headerLine);
        String datePattern = "MMddyyyy";
        Date defaultDate = Utility.getDefaultDate();
        try {
            wcReport = wcReportService.getWCReport(Integer.toString(fs.readInt("organizationCode")), fs.readString("planCode"),fs.readDate("beginDate", datePattern, defaultDate), fs.readDate("endDate", datePattern, defaultDate), fs.readString("reportingType"));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if(jobExecution != null && wcReport != null) {
            ExecutionContext jobContext = jobExecution.getExecutionContext();
            jobContext.put("WCREPORT_OBJECT", wcReport);
        }
    }

    @Override
    public void beforeStep(StepExecution stepExecution) {
        this.jobExecution = stepExecution.getJobExecution();
    }

MemberRecordItemWriter.java 文件

    private int iteration = 0;
    private JobExecution jobExecution;

    @Override
    public void write(List<? extends MemberRecord> records) throws Exception {
        System.out.println("Iteration-" + iteration++);
        Object wcReport = jobExecution.getExecutionContext().get("WCREPORT_OBJECT");
        for (MemberRecord mr : records) {
            //System.out.println(header);
            System.out.println(mr.getLastName());
        }       
    }

    @BeforeStep
    public void beforeStep(StepExecution stepExecution) {
        this.jobExecution = stepExecution.getJobExecution();
    }

谢谢, 维杰

最佳答案

在处理来自 ftp 的传入文件然后处理时,您需要集成 Spring Integration 和 Spring Batch 以创建基于事件的系统。

  1. 配置 Spring Integration 以监听您的 ftp 服务器。
  2. 一旦检测到传入文件,Spring Integration 就会运行一个作业。
  3. Spring Batch 将处理传入的文件并将数据保存到数据库。
  4. 注意:要添加归档功能,您需要将其添加到 Spring Batch 的 JobListener 或 StepListener

关于java - Spring 批问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9596566/

相关文章:

java - Spring 等价于 Seam 的 @Factory 注解

java - StaxEventItemWriter - 文件不可写问题

java - @PostConstruct 与 Spring Batch reader 结合时调用失败

spring - 通过 Grail 的 bean DSL 配置 Jackson 的 ObjectMapper

java - HashMap 仅显示最后一个条目

java - 关于android中java中日期格式的咨询

java - 非空注释和标准 java 包

java - hibernate 事务没有正确回滚

spring - 如何使用FlatFileItemReader和 block 跳过CSV中的空白行

java - 结果集已关闭检索时出错