首页 > 解决方案 > 尽管存在所需的频道,但“在超时内未收到回复”

问题描述

我在我的项目中使用弹簧集成。以下是加载所需配置文件的 web.xml 代码:

<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:TestService/applicationContext.xml</param-value>
    </context-param>
    <servlet>
        <servlet-name>SpringDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value/>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringDispatcherServlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

这是我的applicationContext.xml文件:

<int:annotation-config/>
  <context:component-scan base-package="com.test"/>
  <mvc:annotation-driven />

  <import resource="JobDesigner-springintegration.xml"/>    
  <import resource="DataSourceConfiguration.xml"/>

   <!-- Inbound/Outbound Channels -->
    <int:channel id="httpJobRequest" />
    <int:channel id="httpJobResponse" />

    <int-http:inbound-gateway id="inboundhttpJobRequestGateway"     
        supported-methods="GET, POST" 
        request-channel="httpJobRequest"
        reply-channel="httpJobResponse"     
        path="/jobdesigner"
        reply-timeout="90000"
        error-channel="cs-exceptionHandlingChannel" >

        <int-http:header name="${headerNames.jobName}" expression="#requestParams.src[0]"/>

    </int-http:inbound-gateway>

    <!-- Http Rest Input Buffered Channel -->
    <int:bridge input-channel="httpJobRequest"      output-channel = "jobDesignerInputChannel"  />

</beans>

这是我的JobDesigner-springintegration.xml文件,它加载了所有具有弹簧集成通道的文件。

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

    <import resource="spring-integration/Jobs/*.xml"/>

    <!-- map of namespace prefix to URI -->
    <util:map id="xmlMessageNamespace">
        <entry key="SOAP" value="http://schemas.xmlsoap.org/soap/envelope/" />
    </util:map>

    <bean id="customerServProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="locations">
            <list>
                 <value>classpath:TestService/property-files/*.properties</value>     
            </list>
        </property>
    </bean>

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                 <value>classpath:TestService/property-files/*.properties</value>     
            </list>
        </property>
    </bean>

    <int:channel id="jobDesignerInputChannel" />
    <int:channel id="cs-exceptionHandlingChannel" />

    <bean id="msgHandler" class="com.org.cs.test.jobs.PQMessageHandler" />


    <bean id="headerMapper" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper">   
        <property name="inboundHeaderNames" value="*" />
        <property name="outboundHeaderNames" value="HTTP_REQUEST_HEADERS, Use-200-on-204-response" />
        <property name="userDefinedHeaderPrefix" value="" />
    </bean>

    <int:payload-type-router input-channel="jobDesignerInputChannel"  default-output-channel="xmlMessageChannel">
        <int:mapping type="java.util.HashMap" channel="multipartMessageChannel" />
    </int:payload-type-router>


    <int:chain input-channel="xmlMessageChannel" >
        <int:service-activator  ref="msgHandler" method="test" />

        <int-xml:xpath-header-enricher default-overwrite="true"  should-skip-nulls="true"  >
            <int-xml:header name="${headerNames.legacySystem}"  xpath-expression="//LegacySystem"  evaluation-type="STRING_RESULT"  overwrite="true" />   
        </int-xml:xpath-header-enricher>        


        <int:header-enricher>
            <int:header name="${headerNames.businessArea}" expression="#xpath(payload, '//businessArea/Code', 'boolean') ? null : #xpath(payload, '//businessArea')"/>
        </int:header-enricher>

        <int:router expression="${routing.jobChannel}"/>
    </int:chain>

    <int:chain input-channel="multipartMessageChannel" >
        <int:router expression="${routing.jobChannel}"/>
    </int:chain>    


    <int:chain input-channel="cs-exceptionHandlingChannel">
        <!-- Service Activator to handle the errors --> 
        <int:service-activator  ref="msgHandler" method="handleError" />

        <!-- Router to routing the error messages to appropriate job channel for xsl transormation -->      
        <int:router expression="${routing.jobErrorChannel}"/>
    </int:chain>           
</beans>

从属性文件加载以下属性:

routing.jobChannel=headers.jobDesignerJobName+'-InputChannel'
routing.jobErrorChannel=headers.jobDesignerJobName+'-XsltTransformInputChannel'

这个想法是根据 的值将消息路由到适当的通道"headers.jobDesignerJobName"。访问我们应用程序的主页后,所有频道在部署到 Jboss 服务器时都已成功访问。但是,奇怪的是,如果我们直接尝试使用 http 请求调用通道,则无法访问通道。我通过调试日志消息发现该消息到达 until <int:service-activator ref="msgHandler" method="test" />,但之后它无法触发headers.jobDesignerJobName+'InputChannel'虽然headers.jobDesignerJobName具有有效值。刚刚收到错误:no reply received within timeout

我的 test() 方法只是一个为调试目的添加的虚拟方法:

public Message<?> test(Message<?> inMessage){
        return inMessage;

    }

这里出了什么问题?它与JBOSS会话管理有关吗?如果是这种情况,applicationContext.xml根据我的理解,该文件根本不应该被访问。有人能说出原因吗?

我们使用 Maven 进行依赖管理。Spring 消息传递 jar 由 Spring Integration 传递。

+- org.springframework.integration:spring-integration-core:jar:5.0.6.RELEASE:compile
[INFO] |  +- org.springframework:spring-core:jar:5.0.6.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-jcl:jar:5.0.6.RELEASE:compile
[INFO] |  +- org.springframework:spring-aop:jar:5.0.6.RELEASE:compile
[INFO] |  +- org.springframework:spring-context:jar:5.0.6.RELEASE:compile
[INFO] |  +- org.springframework:spring-messaging:jar:5.0.6.RELEASE:compile
[INFO] |  +- org.springframework:spring-tx:jar:5.0.6.RELEASE:compile
[INFO] |  +- org.springframework.retry:spring-retry:jar:1.2.2.RELEASE:compile
[INFO] |  \- io.projectreactor:reactor-core:jar:3.1.6.RELEASE:compile
[INFO] |     \- org.reactivestreams:reactive-streams:jar:1.0.2:compile

还有其他想法吗?

标签: spring-integration

解决方案


你确定你的msgHandler.test方法返回了一些东西吗?如果它是void或返回null,则流程停止并且确实不会发生任何回复。因此<int-http:inbound-gateway>失败并出现上述错误。

您没有显示重要代码,例如谁订阅了jobDesignerInputChannel. 谁将消息发送到httpJobResponse. 等等。msgHandler.test所有与问题真正相关的东西。但是你展示了一个标准web.xml。请问和问题有什么关系?

更新

很难理解您如此自定义的配置中发生了什么。

我建议您通过 启用<message-history>和记录所有流量<wire-tap>。因此,通过这种方式,您将在日志中看到您的消息如何传递组件以及真正的问题在哪里。

有关更多信息,请参阅文档:

https://docs.spring.io/spring-integration/reference/html/#message-history

https://docs.spring.io/spring-integration/reference/html/#channel-wiretap


推荐阅读