如何使用spring批处理不同格式的文件?
How to process files of different formats using spring batch?
我的要求是轮询两个不同的目录以获取不同格式的文件(PSV 和 CSV)并使用 spring 批处理进行处理。
我使用入站通道适配器轮询目录。但是,我无法找到一种方法来根据文件类型调用相应的 reader 及其分词器和字段映射器。
例如如果是 psv - 调用 PSV reader , PSV line mapper
如果是 csv - 调用 CSVReader , CSV line mapper
如有任何帮助,我们将不胜感激。
谢谢
您可以创建自己的 Reader
: CustomFilesReader
:
public class CustomFilesReader implements InitializingBean{
private List<File> yourFiles= null;
public File read() {
if ((yourFiles!= null) && (yourFiles.size() != 0)) {
return yourFiles.remove(0);
}
return null;
}
//Reading Items from your dir
private void loadItems() {
this.yourFiles= new ArrayList<File>();
// populate the items
}
@Override
public void afterPropertiesSet() throws Exception {
loadItems();
}
}
注册 bean:
<bean id="customFilesReader " class="mypackage.CustomFilesReader "/>
<bean id="myReader"
class="org.springframework.batch.item.adapter.ItemReaderAdapter">
<property name="targetObject" ref="customFilesReader " />
<property name="targetMethod" value="read" />
</bean>
可以对自定义 ItemProcessor
和自定义 ItemWriter
执行相同的操作。
另一种方法是创建类似于 ClassifierCompositeItemProcessor
或 ClassifierCompositeItemWriter
的 class。也就是说,它会取一个Classifier
,一个委托列表ItemReader
,然后根据Classifier
的结果选择正确的ItemReader
。
问题是,您没有 classify 的输入,因为读取尚未完成。这就是为什么我考虑使用 resource
属性 作为 classify 的元素。这是结果:
public class ResourceClassifierCompositeItemReader<T> implements ItemReader<T> {
private Classifier<String, ItemReader<? extends T>> classifier = new ClassifierSupport<String, ItemReader<? extends T>> (null);
private Resource resource;
public void setClassifier(Classifier<String, ItemReader<? extends T>> classifier) {
this.classifier = classifier;
}
@Override
public T read() throws Exception, UnexpectedInputException, ParseException {
return readItem(classifier.classify(resource.getFilename()));
}
private T readItem(ItemReader<? extends T> reader) throws Exception {
return reader.read();
}
public void setResource(Resource resource) {
this.resource = resource;
}
}
现在介绍如何使用它。首先,您需要 MultiResourceItemReader
才能同时读取 .PSV 和 .CSV。然后,您必须将读取委托给 ResourceClassifierCompositeItemReader
。您必须添加一个 BackToBackPatternClassifier
到 class 验证字符串 resource.getFilename()
(即文件名)并相应地调用 ItemReader
(通过 MatcherMap
) .为此,您需要编写自己的 RouterDelegate
(获取文件名,将其拆分以获得扩展名,并将其 return 作为要匹配的字符串)。
感谢您的所有建议。
我采用了不同的方法。我已将项目 reader 和 writer 设置为作业参数。因此,根据文件类型,将调用相应的项目 reader 和 writer
<chunk reader= "#{JobParameter[bean.reader]}" writer="#{JobParameter[bean.writer]}"/>
谢谢
我的要求是轮询两个不同的目录以获取不同格式的文件(PSV 和 CSV)并使用 spring 批处理进行处理。
我使用入站通道适配器轮询目录。但是,我无法找到一种方法来根据文件类型调用相应的 reader 及其分词器和字段映射器。
例如如果是 psv - 调用 PSV reader , PSV line mapper 如果是 csv - 调用 CSVReader , CSV line mapper
如有任何帮助,我们将不胜感激。
谢谢
您可以创建自己的 Reader
: CustomFilesReader
:
public class CustomFilesReader implements InitializingBean{
private List<File> yourFiles= null;
public File read() {
if ((yourFiles!= null) && (yourFiles.size() != 0)) {
return yourFiles.remove(0);
}
return null;
}
//Reading Items from your dir
private void loadItems() {
this.yourFiles= new ArrayList<File>();
// populate the items
}
@Override
public void afterPropertiesSet() throws Exception {
loadItems();
}
}
注册 bean:
<bean id="customFilesReader " class="mypackage.CustomFilesReader "/>
<bean id="myReader"
class="org.springframework.batch.item.adapter.ItemReaderAdapter">
<property name="targetObject" ref="customFilesReader " />
<property name="targetMethod" value="read" />
</bean>
可以对自定义 ItemProcessor
和自定义 ItemWriter
执行相同的操作。
另一种方法是创建类似于 ClassifierCompositeItemProcessor
或 ClassifierCompositeItemWriter
的 class。也就是说,它会取一个Classifier
,一个委托列表ItemReader
,然后根据Classifier
的结果选择正确的ItemReader
。
问题是,您没有 classify 的输入,因为读取尚未完成。这就是为什么我考虑使用 resource
属性 作为 classify 的元素。这是结果:
public class ResourceClassifierCompositeItemReader<T> implements ItemReader<T> {
private Classifier<String, ItemReader<? extends T>> classifier = new ClassifierSupport<String, ItemReader<? extends T>> (null);
private Resource resource;
public void setClassifier(Classifier<String, ItemReader<? extends T>> classifier) {
this.classifier = classifier;
}
@Override
public T read() throws Exception, UnexpectedInputException, ParseException {
return readItem(classifier.classify(resource.getFilename()));
}
private T readItem(ItemReader<? extends T> reader) throws Exception {
return reader.read();
}
public void setResource(Resource resource) {
this.resource = resource;
}
}
现在介绍如何使用它。首先,您需要 MultiResourceItemReader
才能同时读取 .PSV 和 .CSV。然后,您必须将读取委托给 ResourceClassifierCompositeItemReader
。您必须添加一个 BackToBackPatternClassifier
到 class 验证字符串 resource.getFilename()
(即文件名)并相应地调用 ItemReader
(通过 MatcherMap
) .为此,您需要编写自己的 RouterDelegate
(获取文件名,将其拆分以获得扩展名,并将其 return 作为要匹配的字符串)。
感谢您的所有建议。
我采用了不同的方法。我已将项目 reader 和 writer 设置为作业参数。因此,根据文件类型,将调用相应的项目 reader 和 writer
<chunk reader= "#{JobParameter[bean.reader]}" writer="#{JobParameter[bean.writer]}"/>
谢谢