我需要帮助,我使用spring-integration-ftp测试了Spring Boot应用程序,如果我在主类SpringBootFtpApplication中使用它,它可以工作 它运行并将文件从远程服务器复制到我的本地,但它会自动运行。
@SpringBootApplication
public class SpringBootFtpApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootFtpApplication.class, args);
}
@Bean
public SessionFactory<FTPFile> ftpSessionFactory() {
DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
sf.setHost("123.ftpserver.com");
sf.setPort(21);
sf.setUsername("demo");
sf.setPassword("xxxxx");
return new CachingSessionFactory<FTPFile>(sf);
}
@Bean
public FtpInboundFileSynchronizer ftpInboundFileSynchronizer() {
FtpInboundFileSynchronizer fileSynchronizer = new FtpInboundFileSynchronizer(ftpSessionFactory());
fileSynchronizer.setDeleteRemoteFiles(false);
fileSynchronizer.setRemoteDirectory("upload");
fileSynchronizer.setFilter(new FtpSimplePatternFileListFilter("*.txt"));
return fileSynchronizer;
}
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata defaultPoller() {
PollerMetadata pollerMetadata = new PollerMetadata();
pollerMetadata.setTrigger(new PeriodicTrigger(10));
return pollerMetadata;
}
@Bean
@InboundChannelAdapter(channel = "ftpChannel")
public MessageSource<File> ftpMessageSource() {
FtpInboundFileSynchronizingMessageSource source =
new FtpInboundFileSynchronizingMessageSource(ftpInboundFileSynchronizer());
source.setLocalDirectory(new File("ftp-inbound"));
source.setAutoCreateLocalDirectory(true);
source.setLocalFilter(new AcceptOnceFileListFilter<File>());
return source;
}
@Bean
@ServiceActivator(inputChannel = "ftpChannel")
public MessageHandler handler() {
return new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
Object payload = message.getPayload();
if(payload instanceof File){
File f = (File) payload;
System.out.println(f.getName());
}else{
System.out.println(message.getPayload());
}
}
};
}
}
如何将此代码复制到另一个类,然后从另一个控制器类手动启动,例如
public class ImportFromFtpServer(){
/*
@Bean
public SessionFactory<FTPFile> ftpSessionFactory() ...
@Bean
public FtpInboundFileSynchronizer ftpInboundFileSynchronizer() ...
@Bean
@InboundChannelAdapter(channel = "ftpChannel")
public MessageSource<File> ftpMessageSource() ...
@Bean
@ServiceActivator(inputChannel = "ftpChannel")
public MessageHandler handler()...
*/
}
@Controller
public class MyController(){
public class startFtpTransfer(){
ImportFromFtpServer() imp = new ImportFromFtpServer();
//how to call metod for ftp transfer ?
}
}
我尝试将所有代码放在一个类中并放入@Configuration注释,但是这个执行会自动运行,我对执行没有任何控制权,但我想控制何时需要启动此转移
任何提示或帮助都将受到赞赏。 TNX
答案 0 :(得分:0)
如果您只想按需获取文件,请考虑使用出站网关(get
命令)(或直接使用FtpRemoteFileTemplate
)。
为单个文件创建轮询流并不合适。
答案 1 :(得分:0)
@InboundChannelAdapter
有:
/*
{@code SmartLifecycle} options.
Can be specified as 'property placeholder', e.g. {@code ${foo.autoStartup}}.
*/
String autoStartup() default "true";
您可以将其配置为false
。最近当你确实需要这项工作时,你应start()
,因为SourcePollingChannelAdapter
是Lifecycle
实施。
你需要的是注入那个bean:
@Autowired
@Qualifier("springBootFtpApplication.ftpMessageSource.inboundChannelAdapter")
Lifecycle ftpChannelAdapter;
<强>更新强>
由于SourcePollingChannelAdapter
用于@InboundChannelAdapter
注释稍后创建,因此@Autowired
阶段不可行。您的应用程序需要的是手动执行依赖注入。像这样:
@Autowired
private BeanFactory beanFactory;
@GetMapping("/startFtpPolling")
public void startFtpSource() {
this.beanFactory.getBean("demoApplication.ftpMessageSource.inboundChannelAdapter", Lifecycle.class).start();
}
答案 2 :(得分:0)
@ artem-bilan tnx快速回复 我实现了部分解决方案并按照您对autoStartup和此工作的建议放置了这部分代码
@InboundChannelAdapter(channel = "ftpChannel",autoStartup = "false")
public MessageSource<File> ftpMessageSource() {...}
此代码停止自动执行FTP传输。 但是在我按照此代码实现解决方案的第二部分之后
public class FtpLifecycle implements Lifecycle{
@Autowired
@Qualifier("springBootBatchTestApplication.ftpMessageSource.inboundChannelAdapter")
Lifecycle ftpChannelAdapter;
@Override
public boolean isRunning() {
// TODO Auto-generated method stub
return false;
}
@Override
public void start() {
System.out.println("Started...");
ftpChannelAdapter.start();
}
@Override
public void stop() {
// TODO Auto-generated method stub
}
}
然后调用此方法
ftpChannelAdapter.start();
在我的控制器类中我收到了错误
java.lang.NullPointerException: null
at com.company.ftp.FtpLifecycle.start(FtpLifecycle.java:22) ~[classes/:na]
我觉得@Qualifier一定有问题,也许他根本找不到inboundChannelAdapter?有任何建议如何解决这个问题?
编辑23.6
public class FtpLifecycle implements Lifecycle{
private static final Logger LOGGER = LoggerFactory.getLogger(FtpLifecycle.class);
@Autowired
@Qualifier("SpringBootBatchTestApplication.ftpMessageSource.inboundChannelAdapter")
Lifecycle ftpChannelAdapter;
@Autowired
private ApplicationContext appContext;
@Override
public boolean isRunning() {
// TODO Auto-generated method stub
return false;
}
@Override
public void start() {
System.out.println("Started...");
SourcePollingChannelAdapter sp = findTestCaseBean(appContext);
ftpChannelAdapter.start();
}
@Override
public void stop() {
// TODO Auto-generated method stub
}
public static SourcePollingChannelAdapter findTestCaseBean(ApplicationContext appCtx) throws NoSuchBeanDefinitionException {
Map<String, SourcePollingChannelAdapter> testcases = (Map<String, SourcePollingChannelAdapter>) appCtx.getBeansOfType(SourcePollingChannelAdapter.class);
if (testcases.isEmpty()) {
LOGGER.warn("No classes!");
throw new NoSuchBeanDefinitionException(SourcePollingChannelAdapter.class);
} else {
LOGGER.warn("There is classes!");
SourcePollingChannelAdapter retVal = testcases.values().iterator().next();
if (null == retVal) {
throw new NoSuchBeanDefinitionException(SourcePollingChannelAdapter.class);
} else {
return retVal;
}
}
}