Dispatcher没有ftp的订阅者错误

时间:2014-11-19 12:39:00

标签: spring-integration

我在ftp位置删除了一个文件,该文件应由ftp-inbound-adapter选取。该文件保存到本地目录。这个本地目录依次由spring file-inbound-adapter轮询。 filenamegenerator bean在file-inbound-adapter中使用,并动态决定目标。我还发布了另一个关于本地目录中的文件未被删除的问题。这是我面临的问题。 这是我的整个配置

        <util:properties id="someid" location="classpath:config/config.properties"/>
        <mvc:annotation-driven />

    <context:component-scan base-package="com.dms" />
        <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix">
                <value>/WEB-INF/</value>
            </property>
            <property name="suffix">
                <value>.jsp</value>
            </property>
        </bean>
         <context:property-placeholder location="classpath:config/jdbc.properties,classpath:config/config.properties,classpath:config/ftp.properties"/>
          <bean id="dataSource"
            class="org.springframework.jdbc.datasource.DriverManagerDataSource"
            >
            <property name="driverClassName" value="${jdbc.driverClassName}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
            </bean>
         <bean id="sessionFactory"
                class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

                <property name="dataSource">
                      <ref bean="dataSource" />
                </property>

                <property name="hibernateProperties">
                      <props>
                            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                            <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                            <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
                      </props>
                </property>
                <property name="packagesToScan">
                <list>
                    <value>com.dms.entity</value>
                </list>
            </property>
                </bean>
                <tx:annotation-driven />
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

         <bean id="multipartResolver"
            class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

             <!-- setting maximum upload size -->
            <property name="maxUploadSize" value="10485760" />

        </bean>
        <!-- scheduler to pickup temp folder files to permanent location -->

        <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
                 <property name="triggers">
                        <list>
                             <ref bean="simpleTrigger" /> 

                        </list>
                 </property>
          </bean>
         <bean id="dmsFilesDetectionJob" class="com.dms.scheduler.job.DMSFilesDetectionJob">

         </bean>
         <bean id="dmsFilesDetectionJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
            <property name="targetObject" ref="dmsFilesDetectionJob" />
            <property name="targetMethod" value="pollTempFolder" />
            <property name="concurrent" value="false" />
         </bean>
        <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
            <property name="jobDetail" ref="dmsFilesDetectionJobDetail" />
            <!-- <property name="cronExpression" value="1 * * * * ?" /> --> 
            <property name="cronExpression" value="0 0/1 * * * ?" /> 
         </bean>

      <bean id="fileNameGenerator" class="com.dms.util.FileNameGenerator"/>   
        <int-file:inbound-channel-adapter id="filesIn" directory="file:${paths.root}" channel="abc" filter="compositeFilter" >
            <int:poller id="poller" fixed-delay="5000" />

        </int-file:inbound-channel-adapter>
        <int:channel id="abc"/>
        <bean id="compositeFilter" class="org.springframework.integration.file.filters.CompositeFileListFilter">
            <constructor-arg>
                <list>
                    <!-- Ensures that the file is whole before processing it -->
                    <bean class="com.dms.util.CustomFileFilter"/>
                    <!-- Ensures files are picked up only once from the directory -->
                    <bean class="org.springframework.integration.file.filters.AcceptOnceFileListFilter" />
                </list>
            </constructor-arg>
        </bean> 
        <int-file:outbound-channel-adapter channel="abc" id="filesOut"
            directory-expression="@outPathBean.getPath()"
            delete-source-files="true" filename-generator="fileNameGenerator" />
        <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
            <property name="messageConverters">
                <list>
                    <ref bean="jsonMessageConverter"/>
                </list>
            </property>
        </bean>
        <bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
         <!-- <property name="prefixJson" value="false"/> -->
          <!-- <property name="objectMapper">
                <bean class="com.dms.util.HibernateAwareObjectMapper" />
            </property> -->
            <property name="supportedMediaTypes" value="application/json"/>
        </bean>   
        <bean id="ftpClientFactory"
        class="org.springframework.integration.ftp.session.DefaultFtpSessionFactory">
        <property name="host" value="${ftp.ip}"/>
        <property name="port" value="${ftp.port}"/>
        <property name="username" value="${ftp.username}"/>
        <property name="password" value="${ftp.password}"/>
        <property name="clientMode" value="0"/>
        <property name="fileType" value="2"/>
        <property name="bufferSize" value="100000"/>
    </bean>
            <int-ftp:outbound-channel-adapter id="ftpOutbound"
    channel="ftpChannel"
    session-factory="ftpClientFactory"
    charset="UTF-8"
    remote-file-separator="/"
    auto-create-directory="true"
    remote-directory="." 
    use-temporary-file-name="true"
   auto-startup="true" 
    />  
<int-ftp:inbound-channel-adapter id="ftpInbound"
    channel="ftpChannel"
    session-factory="ftpClientFactory"
    charset="UTF-8"
    local-directory="file:${paths.root}"
    delete-remote-files="true"
    temporary-file-suffix=".writing"
    remote-directory="."
    filename-pattern="${file.char}*${file.char}"

    preserve-timestamp="true"
     auto-startup="true">
    <int:poller fixed-rate="1000"/>
</int-ftp:inbound-channel-adapter>
        <int:channel id="ftpChannel" /> 

这是我得到的错误

  18:02:34.655 E|LoggingHandler                          |org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'org.springframework.web.context.WebApplicationContext:/DMS/DMS-dispatcher.ftpChannel'.

此异常不会每次都出现。 正如您所看到的,我添加了自动启动=&#34; true&#34;。已经为通道和适配器使用了唯一的ID。请告诉我这里有什么问题!

由于

2 个答案:

答案 0 :(得分:0)

首先,您的整合流程尚未明确。但我发现你的问题是针对这个

<int-ftp:inbound-channel-adapter id="ftpInbound" channel="ftpChannel"

如果没有人订阅ftpChannel SubscribableChannel

因此,该适配器启动他的工作并向该频道发送消息,但是...... Dispatcher has no subscribers

尝试解决该问题,并找出如何继续。

修改

不确定你在我的回答中发现的内容如此糟糕,以至于它迫使你进行投票。反正。

有一些phase问题before,但正如您所看到的那样已在版本4.1中得到修复。

所以,要立即达到立即修复,你应该这样做:

phase="0x7fffffff" // Integer.MAX_VALUE
默认情况下,

phase0,因此入站通道适配器可能在出站通道适配器之前启动。

或者只升级到最新的Spring Integration

答案 1 :(得分:0)

我只需要使用文件入站通道适配器处理此问题。问题是间歇性的,只有在启动时才会出现。我认为带有轮询器的适配器可以在Spring Integration完全初始化之前开始引入消息。

我的修复是在启动时禁用适配器。适配器的细节不是那么重要,除了它有一个id并设置为不自动启动:

  <!--
    Read files from an "inbox" directory, placing them on an "inbox" channel...
  -->

  <int-file:inbound-channel-adapter id="inboxScanner"
                                    directory="$import{inbox}"
                                    auto-create-directory="true"
                                    channel="fileInbox"
                                    prevent-duplicates="false"
                                    auto-startup="false">
    <int:poller fixed-rate="$import{inbox.scan.rate.seconds}"
                time-unit="SECONDS"
                max-messages-per-poll="$import{inbox.max.imports.per.scan}"/>
  </int-file:inbound-channel-adapter>

然后我进入Spring的应用程序生命周期事件,一旦应用程序上下文完成创建(或刷新),我告诉适配器启动:

  <!--
    Only start the scanner after the application has finished initializing...
  -->

  <int-event:inbound-channel-adapter event-types="org.springframework.context.event.ContextRefreshedEvent"
                                 channel="contextRefreshEvents"/>

  <int:publish-subscribe-channel id="contextRefreshEvents"/>

  <int:outbound-channel-adapter channel="contextRefreshEvents"
                                expression="@inboxScanner.start()" />

&#34;事件&#34;组件来自spring-integration-event。