spring integration-sftp 入站适配器在服务器启动时具有轮询功能

spring integration-sftp inbound adapter with polling facility at server startup

我正在尝试使用 maven web 项目通过 Spring 集成 sftp 文件 需要一个投票设施。如果我启动 SftpInbound.java,轮询工作正常。需要在服务器启动时进行轮询。 java 文件和配置的内容 SftpInbound.java

package com.myproj.integration.bsy.sftp;

import java.io.File;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.file.remote.RemoteFileTemplate;
import org.springframework.integration.file.remote.session.CachingSessionFactory;
import org.springframework.integration.file.remote.session.SessionFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.scheduling.annotation.Scheduled;
import com.myproj.integration.bsy.sftp.*;

import com.jcraft.jsch.ChannelSftp.LsEntry;

public class SftpInboundReceive {

    @Scheduled(fixedRate=5000)
    public void inboundSftpPoll(){
        ConfigurableApplicationContext context =
                new ClassPathXmlApplicationContext("/META-INF/spring/integration/sftp/SftpInboundReceive-context.xml", this.getClass());
        RemoteFileTemplate<LsEntry> template = null;
        String file1 = "a.txt";
        String file2 = "b.txt";
        String file3 = "c.bar";
        new File("local-dir", file1).delete();
        new File("local-dir", file2).delete();
        try {
            PollableChannel localFileChannel = context.getBean("receiveChannel", PollableChannel.class);
            @SuppressWarnings("unchecked")
            SessionFactory<LsEntry> sessionFactory = context.getBean(CachingSessionFactory.class);
            template = new RemoteFileTemplate<LsEntry>(sessionFactory);
            System.out.println("here 1" +template);

            SourcePollingChannelAdapter adapter = context.getBean("sftpInbondAdapter",SourcePollingChannelAdapter.class);
            adapter.start();
            Message<?> received = localFileChannel.receive();
            System.out.println("Received first file message 1: " + received);
            received = localFileChannel.receive();
            System.out.println("Received second file message: " + received);
            received = localFileChannel.receive(1000);
            System.out.println("Third file was received as expected" +received);
        }catch(Exception e){
            e.printStackTrace();
        }
        finally {
            SftpUtils.cleanUp(template, file1, file2, file3);
            //context.close();
        }
    }
    public static void main(String args[])
    {
        SftpInboundReceive oInboundReceiveSample = new SftpInboundReceive();
        oInboundReceiveSample.inboundSftpPoll();
    }
}

xml文件SftpInboundReceive-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:int-sftp="http://www.springframework.org/schema/integration/sftp"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-4.1.xsd
        http://www.springframework.org/schema/integration/sftp http://www.springframework.org/schema/integration/sftp/spring-integration-sftp-4.1.xsd 
         http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.1.xsd">


    <!-- <import resource="SftpSampleCommon.xml"/> -->


             <context:property-placeholder order="1"
            location="classpath:/sftpuser.properties" ignore-unresolvable="true"/>


        <bean id="sftpSessionFactory"
            class="org.springframework.integration.file.remote.session.CachingSessionFactory">
            <constructor-arg ref="defaultSftpSessionFactory" />
        </bean>

        <!-- host=xxx.xx.128.143 port=22 username=xxxuser passphrase= private.keyfile=classpath:META-INF/keys/sftp_rsa -->


        <bean id="defaultSftpSessionFactory" 

            class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">

            <property name="host" value="${sftp.host}" />
            <property name="port" value="${sftp.port}" />
            <property name="user" value="${sftp.username}" />
            <property name="privateKey" value="${private.keyfile}" />
            <property name="privateKeyPassphrase" value="${passphrase}" />
        </bean>



        <!-- username & password from property file... tested <bean id="defaultSftpSessionFactory" 
            class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory"> 
            <property name="host" value="${sftp.host}"/> <property name="port" value="${sftp.port}"/> 
            <property name="user" value="${sftp.username}"/> <property name="password" 
            value="${sftp.password}"/> </bean> -->



        <!-- hardcoded, username & password... tested <bean id="defaultSftpSessionFactory" 
            class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory"> 
            <property name="host" value="xxx.xx.128.143"/> <property name="port" value="22"/> 
            <property name="user" value="xxxuser"/> <property name="password" value="xxxuser@123"/> 
            </bean> -->



        <!-- Inbound channel adapter for SFTP call . with poll facility -->
        <int-sftp:inbound-channel-adapter id="sftpInbondAdapter"
            auto-startup="true" channel="receiveChannel" session-factory="sftpSessionFactory"
            local-directory="file:/target/foo" remote-directory="${sftp.inboundremotedir}"
            auto-create-local-directory="true" delete-remote-files="false"
            filename-pattern="*.txt">
            <int:poller fixed-rate="100000" max-messages-per-poll="1" />
        </int-sftp:inbound-channel-adapter>

        <int:channel id="receiveChannel">
            <int:queue />
        </int:channel>

    </beans>

STackTrace

    p-bio-8080-exec-3][org.springframework.security.web.FilterChainProxy] / at position 5 of 12 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
    16:02:58.368 DEBUG [http-bio-8080-exec-3][org.springframework.security.web.FilterChainProxy] / at position 6 of 12 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
    16:02:58.368 DEBUG [http-bio-8080-exec-3][org.springframework.security.web.FilterChainProxy] / at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
    16:02:58.368 DEBUG [http-bio-8080-exec-3][org.springframework.security.web.FilterChainProxy] / at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
    16:02:58.370 DEBUG [http-bio-8080-exec-3][org.springframework.security.web.FilterChainProxy] / at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
    16:02:58.371 DEBUG [http-bio-8080-exec-3][org.springframework.security.web.authentication.AnonymousAuthenticationFilter] Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
    16:02:58.371 DEBUG [http-bio-8080-exec-3][org.springframework.security.web.FilterChainProxy] / at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
    16:02:58.371 DEBUG [http-bio-8080-exec-3][org.springframework.security.web.FilterChainProxy] / at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
    16:02:58.371 DEBUG [http-bio-8080-exec-3][org.springframework.security.web.FilterChainProxy] / at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
    16:02:58.371 DEBUG [http-bio-8080-exec-3][org.springframework.security.web.util.matcher.AntPathRequestMatcher] Checking match of request : '/'; against '/services/employee/*'
    16:02:58.371 DEBUG [http-bio-8080-exec-3][org.springframework.security.web.access.intercept.FilterSecurityInterceptor] Public object - authentication not attempted
    16:02:58.371 TRACE [http-bio-8080-exec-3][org.springframework.web.context.support.XmlWebApplicationContext] Publishing event in Root WebApplicationContext: org.springframework.security.access.event.PublicInvocationEvent[source=FilterInvocation: URL: /]
    16:02:58.372 DEBUG [http-bio-8080-exec-3][org.springframework.beans.factory.support.DefaultListableBeanFactory] Returning cached instance of singleton bean 'org.springframework.integration.internalMessagingAnnotationPostProcessor'
    16:02:58.372 DEBUG [http-bio-8080-exec-3][org.springframework.security.web.FilterChainProxy] / reached end of additional filter chain; proceeding with original chain
    16:02:58.375 TRACE [http-bio-8080-exec-3][org.springframework.web.servlet.DispatcherServlet] Bound request context to thread: SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.context.HttpSessionSecurityContextRepository$Servlet3SaveToSessionRequestWrapper@1b0b34e]
    16:02:58.376 DEBUG [http-bio-8080-exec-3][org.springframework.web.servlet.DispatcherServlet] DispatcherServlet with name 'Information Exchange Gateway Integration' processing GET request for [/DummyDataIntg/]
    16:02:58.376 TRACE [http-bio-8080-exec-3][org.springframework.web.servlet.DispatcherServlet] Testing handler map [org.springframework.integration.http.inbound.IntegrationRequestMappingHandlerMapping@cdca7] in DispatcherServlet with name 'Information Exchange Gateway Integration'
    16:02:58.378 WARN  [http-bio-8080-exec-3][org.springframework.web.servlet.PageNotFound] No mapping found for HTTP request with URI [/DummyDataIntg/] in DispatcherServlet with name 'Information Exchange Gateway Integration'
    16:02:58.378 DEBUG [http-bio-8080-exec-3][org.springframework.security.web.context.HttpSessionSecurityContextRepository] SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
    16:02:58.378 TRACE [http-bio-8080-exec-3][org.springframework.web.servlet.DispatcherServlet] Cleared thread-bound request context: SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.context.HttpSessionSecurityContextRepository$Servlet3SaveToSessionRequestWrapper@1b0b34e]
    16:02:58.378 DEBUG [http-bio-8080-exec-3][org.springframework.web.servlet.DispatcherServlet] Successfully completed request
    16:02:58.378 TRACE [http-bio-8080-exec-3][org.springframework.web.context.support.XmlWebApplicationContext] Publishing event in WebApplicationContext for namespace 'Information Exchange Gateway Integration-servlet': ServletRequestHandledEvent: url=[/DummyDataIntg/]; client=[127.0.0.1]; method=[GET]; servlet=[Information Exchange Gateway Integration]; session=[null]; user=[null]; time=[6ms]; status=[OK]
    16:02:58.378 TRACE [http-bio-8080-exec-3][org.springframework.web.context.support.XmlWebApplicationContext] Publishing event in Root WebApplicationContext: ServletRequestHandledEvent: url=[/DummyDataIntg/]; client=[127.0.0.1]; method=[GET]; servlet=[Information Exchange Gateway Integration]; session=[null]; user=[null]; time=[6ms]; status=[OK]
    16:02:58.378 DEBUG [http-bio-8080-exec-3][org.springframework.beans.factory.support.DefaultListableBeanFactory] Returning cached instance of singleton bean 'org.springframework.integration.internalMessagingAnnotationPostProcessor'
    16:02:58.378 DEBUG [http-bio-8080-exec-3][org.springframework.security.web.access.ExceptionTranslationFilter] Chain processed normally
    16:02:58.378 DEBUG [http-bio-8080-exec-3][org.springframework.security.web.context.SecurityContextPersistenceFilter] SecurityContextHolder now cleared, as request processing completed
    16:04:37.403 INFO  [task-scheduler-4][org.springframework.integration.file.FileReadingMessageSource] Created message: [GenericMessage [payload=\target\foo\b.txt, headers={timestamp=1420540477403, id=f8c32928-411b-99b7-f4a0-0dd1b119fc44}]]
    16:04:37.403 ERROR [task-scheduler-4][org.springframework.integration.handler.LoggingHandler] \target\foo\b.txt
    16:06:17.403 INFO  [task-scheduler-9][org.springframework.integration.file.FileReadingMessageSource] Created message: [GenericMessage [payload=\target\foo\brjb.txt, headers={timestamp=1420540577403, id=061634bf-0562-962b-e583-53a302cdb0d4}]]
    16:06:17.403 ERROR [task-scheduler-9][org.springframework.integration.handler.LoggingHandler] \target\foo\brjb.txt
    16:07:57.403 INFO  [task-scheduler-10][org.springframework.integration.file.FileReadingMessageSource] Created message: [GenericMessage [payload=\target\foo\d.txt, headers={timestamp=1420540677403, id=abea1188-fc5a-15b0-c40c-73ea686a88c0}]]
    16:07:57.403 ERROR [task-scheduler-10][org.springframework.integration.handler.LoggingHandler] \target\foo\d.txt
    16:09:37.403 INFO  [task-scheduler-4][org.springframework.integration.file.FileReadingMessageSource] Created message: [GenericMessage [payload=\target\foo\g.txt, headers={timestamp=1420540777403, id=461a8e48-6ebf-5d1c-ab3f-ce28e54e00b8}]]
    16:09:37.403 ERROR [task-scheduler-4][org.springframework.integration.handler.LoggingHandler] \target\foo\g.txt
    16:11:17.403 INFO  [task-scheduler-3][org.springframework.integration.file.FileReadingMessageSource] Created message: [GenericMessage [payload=\target\foo\h.txt, headers={timestamp=1420540877403, id=4cbeeceb-5949-0e1c-1492-45ec17172480}]]
    16:11:17.403 ERROR [task-scheduler-3][org.springframework.integration.handler.LoggingHandler] \target\foo\h.txt
    16:12:57.403 INFO  [task-scheduler-9][org.springframework.integration.file.FileReadingMessageSource] Created message: [GenericMessage [payload=\target\foo\p.txt, headers={timestamp=1420540977403, id=3767b4bb-4de4-3178-f693-5ac0bd94a766}]]
    16:12:57.403 ERROR [task-scheduler-9][org.springframework.integration.handler.LoggingHandler] \target\foo\p.txt
    16:14:37.403 INFO  [task-scheduler-6][org.springframework.integration.file.FileReadingMessageSource] Created message: [GenericMessage [payload=\target\foo\wiki.txt, headers={timestamp=1420541077403, id=bd3d0082-9788-fc31-1596-ab7a79186c17}]]
    16:14:37.403 ERROR [task-scheduler-6][org.springframework.integration.handler.LoggingHandler] \target\foo\wiki.txt
error log in java file**strong text**
20:25:52.807 ERROR [task-scheduler-1][org.springframework.integration.handler.LoggingHandler] org.springframework.messaging.MessagingException: Problem occurred while synchronizing remote to local directory; nested exception is org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is org.springframework.core.NestedIOException: Failed to list files; nested exception is 2: No such file
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.synchronizeToLocalDirectory(AbstractInboundFileSynchronizer.java:209)
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizingMessageSource.doReceive(AbstractInboundFileSynchronizingMessageSource.java:167)
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizingMessageSource.doReceive(AbstractInboundFileSynchronizingMessageSource.java:57)
    at org.springframework.integration.endpoint.AbstractMessageSource.receive(AbstractMessageSource.java:64)
    at org.springframework.integration.endpoint.SourcePollingChannelAdapter.receiveMessage(SourcePollingChannelAdapter.java:124)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:192)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint.access[=13=]0(AbstractPollingEndpoint.java:55)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint.call(AbstractPollingEndpoint.java:149)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint.call(AbstractPollingEndpoint.java:146)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:298)
    at org.springframework.integration.util.ErrorHandlingTaskExecutor.run(ErrorHandlingTaskExecutor.java:52)
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
    at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:49)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:292)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
Caused by: org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is org.springframework.core.NestedIOException: Failed to list files; nested exception is 2: No such file
    at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:343)
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.synchronizeToLocalDirectory(AbstractInboundFileSynchronizer.java:167)
    ... 22 more
Caused by: org.springframework.core.NestedIOException: Failed to list files; nested exception is 2: No such file
    at org.springframework.integration.sftp.session.SftpSession.list(SftpSession.java:103)
    at org.springframework.integration.sftp.session.SftpSession.list(SftpSession.java:50)
    at org.springframework.integration.file.remote.session.CachingSessionFactory$CachedSession.list(CachingSessionFactory.java:205)
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.doInSession(AbstractInboundFileSynchronizer.java:171)
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.doInSession(AbstractInboundFileSynchronizer.java:167)
    at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:334)
    ... 23 more
Caused by: 2: No such file
    at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2846)
    at com.jcraft.jsch.ChannelSftp._stat(ChannelSftp.java:2198)
    at com.jcraft.jsch.ChannelSftp._stat(ChannelSftp.java:2215)
    at com.jcraft.jsch.ChannelSftp.ls(ChannelSftp.java:1565)
    at com.jcraft.jsch.ChannelSftp.ls(ChannelSftp.java:1526)
    at org.springframework.integration.sftp.session.SftpSession.list(SftpSession.java:91)
    ... 28 more

您需要了解如何使用 web.xmlWebApplicationInitializer 为 Servlet 3 环境从 Web 应用程序启动 Spring 上下文。在这种情况下,SftpInboundReceive-context.xml 可以是公共 ApplicationContext 的一部分,轮询工具 (<int-sftp:inbound-channel-adapter>) 将在应用程序启动时自动启动,这是在服务器启动时引起的,当最后一个看到您的应用程序的 Web 上下文。

请阅读 Spring 框架的更多文档:http://projects.spring.io/spring-framework/

Spring集成只是EIP扩展,遵循相同的配置和生命周期规则。

我看到您只是使用 Spring Integration 中的 SFTP 示例。您可以在那里找到 Tomcat 和 Spring Boot 的示例。