我需要能够使用SCP轮询目录中的特定文件,一旦文件处理完毕,就需要继续进行轮询。
Spring Batch可以实现吗?
答案 0 :(得分:2)
处理此问题的常用方法是使用Spring Integration。我解决这个问题的方法是使用Spring Integration流程,该流程使用SFTP入站通道适配器来检索文件,然后将传输的名称传递给Spring Batch以启动。该流程实际上类似于我在Spring Batch网络研讨会中的SpringBatchIntegration中的示例:https://github.com/mminella/SpringBatchWebinar
在那个例子中,我使用Twitter来启动这项工作。您唯一需要改变的是SFTP的推特。
答案 1 :(得分:1)
我必须解决相同的问题(但只是访问本地文件系统)并且我没有在框架中找到任何解决方案,所以我最终创建了自己的类来轮询文件并创建资源。我知道这只是一种解决方法,但到目前为止我还没有找到更好的方法。
我不记得在哪里(可能在"重试处理"部分)但我在文档中读到类似"批处理作业不应该尝试解决像文件未找到,连接断开等等,这些错误应该会导致作业引发错误,由操作员处理" 所以我放弃了......
另一方面,Spring Retry是Spring批处理的一部分,现在是一个新的独立库,也许你可以假设文件在那里,如果读者没有找到它,让步骤失败并建立一个&#34 ;重试政策"对于那一步,但对我而言是过度的。
这就是我所做的:
<bean id="resourceFactory"
class="com.mycompany.batch.zip.ResourceFactory">
<property name="retryAttemps" value="${attemps}" />
<property name="timeBetweenAttemps" value="${timeBetweenAttemps}"/>
</bean>
<bean id="myResource"
factory-bean="resourceFactory" factory-method="create" scope="step">
<constructor-arg value="${absolutepath}" type="java.lang.String" />
</bean>
<!--step scope to avoid looking for the file when deployment-->
<bean id="myReader"
class="org.springframework.batch.item.xml.StaxEventItemReader" scope="step">
<property name="fragmentRootElementName" value="retailer" />
<property name="unmarshaller" ref="reportUnmarshaller" />
<property name="resource" ref="myResource" />
</bean>
这是我的班级:
public class ResourceFactory {
public static final Logger LOG= LoggerFactory.getLogger(ResourceFactory.class);
private int retryAttemps;
private long timeBetweenAttemps;
public Resource create(String resource) throws IOException, InterruptedException {
Resource r;
File f=new File(resource);
int attemps=1;
while (!f.exists()) {
if (attemps<this.retryAttemps) {
attemps++;
LOG.warn("File "+resource+" not found, waiting "+timeBetweenAttemps+
" before retrying. Attemp: "+attemps+" of "+this.retryAttemps);
Thread.sleep(this.timeBetweenAttemps);
} else {
throw new FileNotFoundException(resource);
}
if (resource!=null && resource.endsWith(".zip")) {
ZipFile zipFile = new ZipFile(resource);
ZipEntry entry=zipFile.entries().nextElement();
if (entry==null) {
throw new FileNotFoundException("The zip file has no entries inside");
}
//TODO Test if a buffered Stream is faster than the raw InputStream
InputStream is=new BufferedInputStream(zipFile.getInputStream(entry));
r= new InputStreamResource(is);
if (LOG.isInfoEnabled()) {
int size=(int)entry.getSize();
LOG.info("Opening a compressed file of "+size+" bytes");
}
} else {
LOG.info("Opening a regular file");
r= new FileSystemResource(f);
}
}
return r;
}
}
如果有人知道更好的方法,我很乐意删除这个答案(并实施新的解决方案)
PS:顺便说一下,我在查看这篇文章时发现我的代码中有一些错误,所以对我而言,即使没有其他答案也是如此:)