Spring 批分类器复合项目编写器出错
Error with Spring batch Classifier Composite Item Writer
我基本上必须为每个 file_id 每种货币(即 usd、zar 等)生成多个 xml 文件,这些交易都在 1 DB table 中。我是否为每种货币创建一个复合编写器,并在我的项目处理器上过滤我从数据库中读取的每种不同货币。或者我可以对每个 file_id 的每种货币使用多个步骤吗?我一直在努力寻找解决此问题的 Springbatch 解决方案。
每个文件和货币的文件名资源都不同。例如我可以收到 file_id=1 currency=USD 需要 1 个文件 'USD20051701 with 01 the file sequence'。我还可以获得两个文件 file_id 1 & 2 for Currency ='ZAR' 并且需要两个文件 'ZAR20051701' & 'ZAR20051702' 01 & 02 文件序列。
我使用这个 link 作为其中一个帖子的指南。
我收到此跟踪日志
Log File
请帮忙,我在尝试调试日志屏幕截图时遇到了困难。我已经编写了一个分类器来写入 3 个不同的文件,每种货币,但我收到错误
@Bean
public ClassifierCompositeItemWriter<Settlement> classifierCompositeItemWriter
( ItemWriter<Settlement> ZMWItemWriter,
ItemWriter<Settlement> USDItemWriter,
ItemWriter<Settlement> ZARItemWriter
) {
ClassifierCompositeItemWriter<Settlement> classifierCompositeItemWriter = new ClassifierCompositeItemWriter<>();
classifierCompositeItemWriter.setClassifier(new Classifier<Settlement, ItemWriter<? super Settlement>>() {
@Override
public ItemWriter<? super Settlement> classify(Settlement settlement) {
List<SettlementHeader> settlementheader= new ArrayList<SettlementHeader>();
SettlementHeader header = new SettlementHeader ();
settlementheader.add(header);
settlement.setSettlementHeader(settlementheader);
if (header.getCurrency().equalsIgnoreCase("ZMW")) {
return ZMWItemWriter;
}
else if (header.getCurrency().equalsIgnoreCase("USD")) {
return USDItemWriter;
}
else {
return ZARItemWriter;}
}
});
return classifierCompositeItemWriter;
}
@Qualifier ("USDItemWriter")
@Bean(destroyMethod="")
public NoRootStaxEventItemWriter<Settlement> USDItemWriter() throws Exception {
NoRootStaxEventItemWriter<Settlement> ItemWriter = new NoRootStaxEventItemWriter<>();
FileSystemResource resource = new FileSystemResource("FileUSD1.xml");
ItemWriter.setName("USDItemWriter");
ItemWriter.setResource(resource);
marshaller.setPackagesToScan("com.model");
ItemWriter.setMarshaller(marshaller);
ItemWriter.afterPropertiesSet();
return ItemWriter;
}
@Primary
@Qualifier("ZARItemWriter")
@Bean(destroyMethod="")
public NoRootStaxEventItemWriter<Settlement> ZARItemWriter() throws Exception {
NoRootStaxEventItemWriter<Settlement> ItemWriter = new NoRootStaxEventItemWriter<>();
FileSystemResource resource = new FileSystemResource("FileZAR1.xml");
ItemWriter.setName("ZARItemWriter");
ItemWriter.setResource(resource);
marshaller.setPackagesToScan("com.model");
ItemWriter.setMarshaller(marshaller);
ItemWriter.afterPropertiesSet();
return ItemWriter;
}
@Qualifier("ZMWItemWriter")
@Bean(destroyMethod="")
public NoRootStaxEventItemWriter<Settlement> ZMWItemWriter() throws Exception {
NoRootStaxEventItemWriter<Settlement> ItemWriter = new NoRootStaxEventItemWriter<>();
FileSystemResource resource = new FileSystemResource("FileZMW1.xml");
ItemWriter.setName("ZMWItemWriter");
ItemWriter.setResource(resource);
marshaller.setPackagesToScan("com.model");
ItemWriter.setMarshaller(marshaller);
ItemWriter.afterPropertiesSet();
return ItemWriter;
}
请检查下面的示例,看看它是否适合您。您创建了一个 Map 的 Writer,以避免每次都实例化一个新的 Writer。
写入器由(FileId、ProcessDate、Detail Currency)唯一标识:
String fileNameKey = item.getHeader().getFileId() + item.getHeader().getProcessDate().toString() + settlementDetail.getCurrency();
这里是作者的代码:
@Component
public class SettlementWriter implements ItemStream, ItemWriter<Settlement> {
private final Map<String, StaxEventItemWriter<Settlement>> writers = new HashMap<>();
private ExecutionContext executionContext;
@Autowired
private Marshaller marshaller;
@Override
public void open(ExecutionContext executionContext) throws ItemStreamException {
this.executionContext = executionContext;
}
@Override
public void update(ExecutionContext executionContext) throws ItemStreamException {
}
@Override
public void close() throws ItemStreamException {
for (StaxEventItemWriter f : writers.values()) {
f.close();
}
}
@Override
public void write(List<? extends Settlement> items) throws Exception {
for (Settlement item : items) {
for (SettlementDetail det : item.getDetails()) {
StaxEventItemWriter<Settlement> detailWriter = getFlatFileItemWriter(item, det);
detailWriter.write(Arrays.asList(item));
}
}
}
public StaxEventItemWriter<Settlement> getFlatFileItemWriter(Settlement item, SettlementDetail settlementDetail) {
String fileNameKey = item.getHeader().getFileId() + item.getHeader().getFilename() + settlementDetail.getCurrency();
StaxEventItemWriter<Settlement> itemWriter = writers.get(fileNameKey);
if (itemWriter == null) {
itemWriter = new StaxEventItemWriter<>();
try {
FileSystemResource resource = new FileSystemResource(fileNameKey+".xml");
itemWriter.setName(fileNameKey);
itemWriter.setResource(resource);
marshaller.setPackagesToScan("com.model");
itemWriter.setMarshaller(marshaller);
itemWriter.afterPropertiesSet();
itemWriter.open(executionContext);
} catch (Exception e) {
e.printStackTrace();
}
writers.put(fileNameKey, itemWriter);
}
return itemWriter;
}
}
希望对您有所帮助。
我基本上必须为每个 file_id 每种货币(即 usd、zar 等)生成多个 xml 文件,这些交易都在 1 DB table 中。我是否为每种货币创建一个复合编写器,并在我的项目处理器上过滤我从数据库中读取的每种不同货币。或者我可以对每个 file_id 的每种货币使用多个步骤吗?我一直在努力寻找解决此问题的 Springbatch 解决方案。
每个文件和货币的文件名资源都不同。例如我可以收到 file_id=1 currency=USD 需要 1 个文件 'USD20051701 with 01 the file sequence'。我还可以获得两个文件 file_id 1 & 2 for Currency ='ZAR' 并且需要两个文件 'ZAR20051701' & 'ZAR20051702' 01 & 02 文件序列。
我使用这个 link 作为其中一个帖子的指南。
我收到此跟踪日志 Log File
请帮忙,我在尝试调试日志屏幕截图时遇到了困难。我已经编写了一个分类器来写入 3 个不同的文件,每种货币,但我收到错误
@Bean
public ClassifierCompositeItemWriter<Settlement> classifierCompositeItemWriter
( ItemWriter<Settlement> ZMWItemWriter,
ItemWriter<Settlement> USDItemWriter,
ItemWriter<Settlement> ZARItemWriter
) {
ClassifierCompositeItemWriter<Settlement> classifierCompositeItemWriter = new ClassifierCompositeItemWriter<>();
classifierCompositeItemWriter.setClassifier(new Classifier<Settlement, ItemWriter<? super Settlement>>() {
@Override
public ItemWriter<? super Settlement> classify(Settlement settlement) {
List<SettlementHeader> settlementheader= new ArrayList<SettlementHeader>();
SettlementHeader header = new SettlementHeader ();
settlementheader.add(header);
settlement.setSettlementHeader(settlementheader);
if (header.getCurrency().equalsIgnoreCase("ZMW")) {
return ZMWItemWriter;
}
else if (header.getCurrency().equalsIgnoreCase("USD")) {
return USDItemWriter;
}
else {
return ZARItemWriter;}
}
});
return classifierCompositeItemWriter;
}
@Qualifier ("USDItemWriter")
@Bean(destroyMethod="")
public NoRootStaxEventItemWriter<Settlement> USDItemWriter() throws Exception {
NoRootStaxEventItemWriter<Settlement> ItemWriter = new NoRootStaxEventItemWriter<>();
FileSystemResource resource = new FileSystemResource("FileUSD1.xml");
ItemWriter.setName("USDItemWriter");
ItemWriter.setResource(resource);
marshaller.setPackagesToScan("com.model");
ItemWriter.setMarshaller(marshaller);
ItemWriter.afterPropertiesSet();
return ItemWriter;
}
@Primary
@Qualifier("ZARItemWriter")
@Bean(destroyMethod="")
public NoRootStaxEventItemWriter<Settlement> ZARItemWriter() throws Exception {
NoRootStaxEventItemWriter<Settlement> ItemWriter = new NoRootStaxEventItemWriter<>();
FileSystemResource resource = new FileSystemResource("FileZAR1.xml");
ItemWriter.setName("ZARItemWriter");
ItemWriter.setResource(resource);
marshaller.setPackagesToScan("com.model");
ItemWriter.setMarshaller(marshaller);
ItemWriter.afterPropertiesSet();
return ItemWriter;
}
@Qualifier("ZMWItemWriter")
@Bean(destroyMethod="")
public NoRootStaxEventItemWriter<Settlement> ZMWItemWriter() throws Exception {
NoRootStaxEventItemWriter<Settlement> ItemWriter = new NoRootStaxEventItemWriter<>();
FileSystemResource resource = new FileSystemResource("FileZMW1.xml");
ItemWriter.setName("ZMWItemWriter");
ItemWriter.setResource(resource);
marshaller.setPackagesToScan("com.model");
ItemWriter.setMarshaller(marshaller);
ItemWriter.afterPropertiesSet();
return ItemWriter;
}
请检查下面的示例,看看它是否适合您。您创建了一个 Map 的 Writer,以避免每次都实例化一个新的 Writer。
写入器由(FileId、ProcessDate、Detail Currency)唯一标识:
String fileNameKey = item.getHeader().getFileId() + item.getHeader().getProcessDate().toString() + settlementDetail.getCurrency();
这里是作者的代码:
@Component
public class SettlementWriter implements ItemStream, ItemWriter<Settlement> {
private final Map<String, StaxEventItemWriter<Settlement>> writers = new HashMap<>();
private ExecutionContext executionContext;
@Autowired
private Marshaller marshaller;
@Override
public void open(ExecutionContext executionContext) throws ItemStreamException {
this.executionContext = executionContext;
}
@Override
public void update(ExecutionContext executionContext) throws ItemStreamException {
}
@Override
public void close() throws ItemStreamException {
for (StaxEventItemWriter f : writers.values()) {
f.close();
}
}
@Override
public void write(List<? extends Settlement> items) throws Exception {
for (Settlement item : items) {
for (SettlementDetail det : item.getDetails()) {
StaxEventItemWriter<Settlement> detailWriter = getFlatFileItemWriter(item, det);
detailWriter.write(Arrays.asList(item));
}
}
}
public StaxEventItemWriter<Settlement> getFlatFileItemWriter(Settlement item, SettlementDetail settlementDetail) {
String fileNameKey = item.getHeader().getFileId() + item.getHeader().getFilename() + settlementDetail.getCurrency();
StaxEventItemWriter<Settlement> itemWriter = writers.get(fileNameKey);
if (itemWriter == null) {
itemWriter = new StaxEventItemWriter<>();
try {
FileSystemResource resource = new FileSystemResource(fileNameKey+".xml");
itemWriter.setName(fileNameKey);
itemWriter.setResource(resource);
marshaller.setPackagesToScan("com.model");
itemWriter.setMarshaller(marshaller);
itemWriter.afterPropertiesSet();
itemWriter.open(executionContext);
} catch (Exception e) {
e.printStackTrace();
}
writers.put(fileNameKey, itemWriter);
}
return itemWriter;
}
}
希望对您有所帮助。