带ftp的Spring引导应用程序
我需要帮助,我已经用SpringIntegrationFTP测试了SpringBoot应用程序,如果我在主类SpringBootFTP应用程序中使用它,它就会工作 它运行并将文件从远程服务器复制到我的本地位置,但它会自动工作带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
@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;
}
}
}