带ftp的Spring引导应用程序

带ftp的Spring引导应用程序,spring,spring-boot,spring-integration,Spring,Spring Boot,Spring Integration,我需要帮助,我已经用SpringIntegrationFTP测试了SpringBoot应用程序,如果我在主类SpringBootFTP应用程序中使用它,它就会工作 它运行并将文件从远程服务器复制到我的本地位置,但它会自动工作 @SpringBootApplication public class SpringBootFtpApplication { public static void main(String[] args) { SpringApplication.ru

我需要帮助,我已经用SpringIntegrationFTP测试了SpringBoot应用程序,如果我在主类SpringBootFTP应用程序中使用它,它就会工作 它运行并将文件从远程服务器复制到我的本地位置,但它会自动工作

@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());
                 }
             }

         };
     }
}
@springboot应用程序
公共类SpringBootFTP应用程序{
公共静态void main(字符串[]args){
run(SpringBootFtpApplication.class,args);
}
@豆子
公共会话工厂ftpSessionFactory(){
DefaultFtpSessionFactory sf=新的DefaultFtpSessionFactory();
setHost(“123.ftpserver.com”);
sf.设置端口(21);
sf.setUsername(“演示”);
sf.设置密码(“xxxxx”);
返回新的CachingSessionFactory(sf);
}
@豆子
公共FtpInboundFileSynchronizer FtpInboundFileSynchronizer(){
FtpInboundFileSynchronizer fileSynchronizer=新的FtpInboundFileSynchronizer(ftpSessionFactory());
fileSynchronizer.setDeleteRemoteFiles(false);
setRemoteDirectory(“上载”);
setFilter(新的FtpSimplePatternFileListFilter(“*.txt”);
返回文件同步器;
}
@Bean(name=PollerMetadata.DEFAULT\u POLLER)
公共PollerMetadata defaultPoller(){
PollerMetadata PollerMetadata=新PollerMetadata();
设置触发器(新周期触发器(10));
返回pollerMetadata;
}
@豆子
@InboundChannelAdapter(channel=“ftpcchannel”)
public MessageSource ftpMessageSource(){
FtpInboundFileSynchronizingMessageSource源=
新的FtpInboundFileSynchronizingMessageSource(ftpInboundFileSynchronizer());
setLocalDirectory(新文件(“ftp入站”);
source.setAutoCreateLocalDirectory(true);
setLocalFilter(新的AcceptOnceFileListFilter());
返回源;
}
@豆子
@ServiceActivator(inputChannel=“ftpChannel”)
public MessageHandler(){
返回新的MessageHandler(){
@凌驾
public void handleMessage(消息消息消息)引发MessaginException{
对象负载=message.getPayload();
if(文件的有效负载实例){
文件f=(文件)有效载荷;
System.out.println(f.getName());
}否则{
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 ? 
 }
}
公共类ImportFromFtpServer(){
/*
@豆子
公共会话工厂ftpSessionFactory()。。。
@豆子
公共FtpInboundFileSynchronizer FtpInboundFileSynchronizer()。。。
@豆子
@InboundChannelAdapter(channel=“ftpcchannel”)
public MessageSource ftpMessageSource()。。。
@豆子
@ServiceActivator(inputChannel=“ftpChannel”)
公共消息处理程序()。。。
*/
}
@控制器
公共类MyController(){
公共类startFtpTransfer(){
ImportFromFtpServer()imp=新的ImportFromFtpServer();
//如何调用metod进行ftp传输?
}
}
我尝试将所有代码放在一个类中,并放置@Configuration注释,但是这个执行会自动运行,我对执行没有任何控制权,但我想控制这个传输何时需要开始


任何提示或帮助都将不胜感激。如果您只想按需获取文件,请考虑使用出站网关(<代码>获取< /COD>命令)(或者直接使用<代码> ftPrimTeFieleMePoels>代码>)。
为单个文件创建轮询流实际上并不合适。

InboundChannelAdapter具有:

/*
 {@code SmartLifecycle} options.
 Can be specified as 'property placeholder', e.g. {@code ${foo.autoStartup}}.
 */
String autoStartup() default "true";
您可以将其配置为
false
。最近,当您确实需要从中获得工作时,您应该
start()
它,因为
SourcePollingChannelAdapter
生命周期
实现

您需要的是注入该bean:

@Autowired
@Qualifier("springBootFtpApplication.ftpMessageSource.inboundChannelAdapter")
Lifecycle ftpChannelAdapter;
更新

由于
SourcePollingChannelAdapter
s用于
@InboundChannelAdapter
注释创建稍晚,因此
@Autowired
阶段不可行。您需要在应用程序中手动执行依赖项注入。大概是这样的:

@Autowired
private BeanFactory beanFactory;

@GetMapping("/startFtpPolling")
public void startFtpSource() {
    this.beanFactory.getBean("demoApplication.ftpMessageSource.inboundChannelAdapter", Lifecycle.class).start();
}

@快速回复的artem bilan tnx 我实现了您解决方案的一部分,并将这部分代码按照您对autoStartup和这项工作的建议放置

@InboundChannelAdapter(channel = "ftpChannel",autoStartup = "false")
public MessageSource<File> ftpMessageSource() {...}
然后调用这个方法

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;
        }
    }
}
公共类FtpLifecycle实现生命周期{
私有静态最终记录器Logger=LoggerFactory.getLogger(FtpLifecycle.class);
@自动连线
@限定符(“SpringBootBatchTestApplication.ftpMessageSource.inboundChannelAdapter”)
全生命周期光纤通道适配器;
@自动连线
私有应用上下文appContext;
@凌驾
公共布尔值正在运行(){
//TODO自动生成的方法存根
返回false;
}
@凌驾
公开作废开始(){
System.out.println(“已启动…”);
SourcePollingChannelAdapter sp=findTestCaseBean(appContext);
ftpChannelAdapter.start();
}
@凌驾
公共停车场(){
//TODO自动生成的方法存根
}
公共静态SourcePollingChannelAdapter findTestCaseBean(ApplicationContext appCtx)抛出NoSuchBean定义异常{
Map testcases=(Map)appCtx.getBeansOfType(SourcePollingChannelAdapter.class);
if(testcases.isEmpty()){
LOGGER.warn(“无类!”);
抛出新的NoSuchBeanDefinitionException(SourcePollingChannelAdapter.class);
}否则{
LOGGER.warn(“有类!”);
SourcePollingChannelAdapter retVal=testcases.values().iterator().next();
if(null==retVal){
抛出新的NoSuchBeanDefinitionExceptio
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;
        }
    }
}