Spring batch 获取OnSkipRead项的路径
是否有方法获取无法读取的输入文件的位置,以便在Spring batch 获取OnSkipRead项的路径,spring-batch,Spring Batch,是否有方法获取无法读取的输入文件的位置,以便在SkipListener中使用它 示例: MySkipListener将无法处理或写入的每个文件移动到错误位置: @Override public void onSkipInWrite(MyFileObject arg0, Throwable arg1) { logger.error("onSkipInWrite "); logToErrorDirectory(arg0.getPath(), arg1);
SkipListener
中使用它
示例:My
SkipListener
将无法处理或写入的每个文件移动到错误位置:
@Override
public void onSkipInWrite(MyFileObject arg0, Throwable arg1) {
logger.error("onSkipInWrite ");
logToErrorDirectory(arg0.getPath(), arg1);
}
@Override
public void onSkipInProcess(MyFileObject arg0, Throwable arg1) {
logger.error("onSkipInProcess ");
logToErrorDirectory(arg0.getPath(), arg1);
}
@Override
public void onSkipInRead(Throwable arg1) {
// WHAT TO DO HERE
}
当项目(.xml
文件)也无法读取时,我需要做同样的事情。
我的配置:
<bean id="ExportPatentReader"
class="org.springframework.batch.item.file.MultiResourceItemReader"
scope="step">
<property name="resources" value="file:SomeFolder/*.xml'</property>
<property name="delegate" ref="staxPatentReader"></property>
<property name="strict" value="true"></property>
</bean>
<bean id="staxPatentReader" class="org.springframework.batch.item.xml.StaxEventItemReader"
scope="step">
<property name="fragmentRootElementName" value="Root" />
<property name="unmarshaller" ref="patentMarshaller" />
</bean>
<bean id="patentMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.company.MyFileObject</value>
</list>
</property>
</bean>
问题可能是每次提交完成后,ExecutionContext
都会更新,但找不到解决方法对于记录期间的更新,打印的步骤执行看起来是这样的:
stepExecution:id=6,version=2,name=partitionedStep:partition4,status=STARTED,exitStatus=EXECUTING,readCount=10,filterCount=0,writeCount=10 readSkipCount=2,writeSkipCount=0,processSkipCount=0,commount=1,backrollcount=0,exitDescription=
所以我认为正确的索引可能是每个提交的
项+MultiResourceReader.index的组合
还有一件事。。。我忘了在开头提到我使用partitioner
读取文件,尽管不确定这是否会影响结果
我越是使用SkipListener
,我就越认为更容易的解决方案是编写一个自定义读取器,至少替换StaxEventReader
:DMultiResourceItemReader
通过索引跟踪它在ExecutionContext
中处理的文件。当资源[]
被注入读卡器时,我们按文件名对数组进行排序。之后,我们在每次更新时将当前文件的索引存储在步骤的ExecutionContext
中。我想您可以在您的SkipListener
中实现相同的逻辑。将相同的资源数组注入侦听器,对其进行排序,然后将索引从ExecutionContext
中拉出。您可以在这里的MultiResourceItemReader
代码中看到这一点:我放弃了建议的解决方案,因为我无法让它与提交间隔>1一起工作
解决我问题的肮脏解决方案:
自定义读卡器
以替换statxeventitemreader
==>
在自定义读取器的read()
中添加了onSkipInRead()的逻辑
为了解决这个问题,我修改了read()
@Override
public void setResource(Resource arg0) {
resource = arg0;
// true for new resource
ResourceState = true;
}
@Override
public MyFileObject read() throws Exception {
MyFileObject item = null;
/*
* Run only for a new Resource
*/
if (ResourceState == true) {
logger.debug("Reading: " + resource.getFileName());
try {
// Actual reading
item = (MyFileObject) unmarshaller.unmarshal(resource.getFile());
} catch (Exception e) {
logger.error("Error while reading: " + resource.getFilename());
logToErrorDirectory(resource, errorPath, e);
}
/*
* Finished reading, resourceState=false
*/
ResourceState = false;
}
return item;
}
不是很喜欢这个解决方案,但解决了我的问题 这是一个非常有趣的想法,对于commit interval=1非常有效,但对于更大的一个则不行。我更新了我的问题,提供了更多细节
@Override
public void setResource(Resource arg0) {
resource = arg0;
// true for new resource
ResourceState = true;
}
@Override
public MyFileObject read() throws Exception {
MyFileObject item = null;
/*
* Run only for a new Resource
*/
if (ResourceState == true) {
logger.debug("Reading: " + resource.getFileName());
try {
// Actual reading
item = (MyFileObject) unmarshaller.unmarshal(resource.getFile());
} catch (Exception e) {
logger.error("Error while reading: " + resource.getFilename());
logToErrorDirectory(resource, errorPath, e);
}
/*
* Finished reading, resourceState=false
*/
ResourceState = false;
}
return item;
}