如何动态地将资源名称放入 FlatFileItemWriter

How to put resourse name in FlatFileItemWriter dynamically

我想在ItemWriter中动态添加资源名称,名称的前缀来自ItemReader中调用的存储过程。 每次读取时,值都会不同,因此它会自动创建一个不同的文件。 这是片段:-

<bean id="achFlatFileWriter" class="org.springframework.batch.item.file.FlatFileItemWriter"
        scope="step">
        <property name="resource" value="#{jobParameters['settlementTimestamp']}**#{VALUE_FROM_READER}**.MPS.txt" />
        <property name="shouldDeleteIfExists" value="true" />
        <property name="lineAggregator">
            <bean
                class="org.springframework.batch.item.file.transform.FormatterLineAggregator">
                <property name="fieldExtractor">
                    <bean
                        class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
                        <property name="names" value="writeToFile" />
                    </bean>
                </property>
                <property name="format" value="%s" />
            </bean>
        </property>

    </bean>

这里VALUE_FROM_READER会来自reader, 我尝试通过侦听器将值添加到工作上下文中,但没有帮助。任何方法将不胜感激。

您可以创建一个包含该资源的 bean。 你在你的 reader 中设置它并在你的作家中阅读它。

另一种使用 JavaConfig 的方法,在 Config 文件中使用 属性,在 Reader 中设置它并在 writer 中读取它。我已经快速设置了我的环境,因此您可以改进 rosource 名称 属性 的范围以避免 multiple/concurrent read/write.

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
....

public String getResourceName() {
        return resourceName;
    }

.....

@Bean
      public ItemReader<GeData> reader() throws Exception {     
        JdbcCursorItemReader<GeData> reader = new JdbcCursorItemReader<GeData>();
        reader.setDataSource(DBConfiguration.getDataSource());
        reader.setRowMapper(rowMapper);
        reader.setSql("....");
        setResourceName("resourceNameFromReader.txt");
        return reader;
    }

......
......

@Bean
    public ItemWriter<GeData> writer(DataSource dataSource) {   
        MyItemWriter writer = new MyItemWriter();  
        writer.setResource(new FileSystemResource("E:\" + getResourceName()));
        return writer;
    }

我已经在我的配置中尝试过它并且可以正常工作。希望这有帮助。

"ClassifierCompositeItemWriter" 成功了。

这是详细信息

工作中-

<chunk reader="achFileHeaderReader" processor="achFileContentProcessor" writer="achFileContentWriter" commit-interval="1" >
                <streams>
                    <stream ref="AItemWriter" />
                    <stream ref="BItemWriter" />
                    <stream ref="CItemWriter" />
                </streams>
            </chunk>

作家BEAN-

<bean id="classifier"  class="org.springframework.classify.BackToBackPatternClassifier">
<property name="routerDelegate">
    <bean class="com.abc.myabc.writer.ItemCodeClassifier" >
        <property name="contextInjector" ref="stepExecutionContextInjector"></property>
    </bean>
</property>
<property name="matcherMap">
    <map>
    <entry key="A" value-ref="AItemWriter" />
    <entry key="B" value-ref="BItemWriter" />
    <entry key="C" value-ref="CItemWriter" />
    </map>
</property>
</bean>

1.Inside ItemCodeClassifier 编写返回资源后缀字符串的逻辑。

2.Inject 委托bean分别给不同资源名的AItemWriter,BItemWriter,CItemWriter。

到目前为止,一个缺点是您必须对不同的 ItemWriters 进行硬编码