问题
I am using MultiResourceItemReader in Spring Batch for reading multiple XML files and I want to get current resource.Here is my configuration:
public class MultiFileResourcePartitioner extends MultiResourceItemReader<MyObject> {
@Override
public void update(final ExecutionContext pExecutionContext) throws ItemStreamException {
super.update(pExecutionContext);
if (getCurrentResource() != null && getCurrentResource().getFilename() != null) {
System.out.println(\"update:\" + getCurrentResource().getFilename());
}
}
}
And my reader:
<bean id=\"myMultiSourceReader\"
class=\"mypackage.MultiFileResourcePartitioner\">
<property name=\"resources\" value=\"file:${input.directory}/*.xml\" />
</bean>
The code above read XML files correctly but the method getCurrentResources() return null.
By debugging, the batch enter to update method
Please help!
回答1:
There is a specific interface for this problem called ResourceAware: it's purpouse is to inject current resource into objects read from a MultiResourceItemReader.
Check this thread for further information.
回答2:
I tried it with a simple Listener for logging the current resource from a injected {@link MultiResourceItemReader}. Saves the value to the StepExecutionContext.
To get it working with a step scoped MultiResourceItemReader i access the proxy directly, see http://forum.springsource.org/showthread.php?120775-Accessing-the-currently-processing-filename, https://gist.github.com/1582202 and https://jira.springsource.org/browse/BATCH-1831.
public class GetCurrentResourceChunkListener implements ChunkListener, StepExecutionListener {
private StepExecution stepExecution;
private Object proxy;
private final List<String> fileNames = new ArrayList<>();
public void setProxy(Object mrir) {
this.proxy = mrir;
}
@Override
public void beforeStep(StepExecution stepExecution) {
this.stepExecution = stepExecution;
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
return stepExecution.getExitStatus();
}
@Override
public void beforeChunk(ChunkContext cc) {
if (proxy instanceof Advised) {
try {
Advised advised = (Advised) proxy;
Object obj = advised.getTargetSource().getTarget();
MultiResourceItemReader mrirTarget = (MultiResourceItemReader) obj;
if (mrirTarget != null
&& mrirTarget.getCurrentResource() != null
&& !fileNames.contains(mrirTarget.getCurrentResource().getFilename())) {
String fileName = mrirTarget.getCurrentResource().getFilename();
fileNames.add(fileName);
String index = String.valueOf(fileNames.indexOf(fileName));
stepExecution.getExecutionContext().put("current.resource" + index, fileName);
}
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
@Override
public void afterChunk(ChunkContext cc) {
}
@Override
public void afterChunkError(ChunkContext cc) {
}
}
see https://github.com/langmi/spring-batch-examples-playground for a working example - look for "GetCurrentResource..."
来源:https://stackoverflow.com/questions/22993633/get-current-resource-name-using-multiresourceitemreader-spring-batch