Email Spring集成:邮件错误和HTTP网关响应

Email Spring集成:邮件错误和HTTP网关响应,email,spring-integration,Email,Spring Integration,我的用例很简单。我想处理由于无法访问系统而导致的异常,根据配置的重试策略执行重试,在满足重试阈值时发送电子邮件,并向调用者返回自定义响应 我面临的挑战是,我无法既发送电子邮件,又将回复返回给来电者。由于我最初使用的是int-mail:outbound-channel适配器,因此我预期会出现这种行为,因为这是一个单向组件: <int:chain input-channel="defaultErrorChannel"> <int:service-activ

我的用例很简单。我想处理由于无法访问系统而导致的异常,根据配置的重试策略执行重试,在满足重试阈值时发送电子邮件,并向调用者返回自定义响应

我面临的挑战是,我无法既发送电子邮件,又将回复返回给来电者。由于我最初使用的是
int-mail:outbound-channel适配器
,因此我预期会出现这种行为,因为这是一个单向组件:

    <int:chain input-channel="defaultErrorChannel"> 
        <int:service-activator id="mailMessageActivator" expression="@mailHandler.process(payload)" />
        <int-mail:outbound-channel-adapter mail-sender="mailSender" />
    </int:chain>   
错误处理

    <int:channel id="defaultErrorChannel"/>
    <int:channel id="errorResponses"/>

    <!-- 
      ExponentialBackOffPolicy.multipler is applied to wait time over each retry attempt
      with a ExponentialBackOffPolicy.maximum configured.        
    -->
    <bean id="retryWithBackoffAdviceSession" class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
        <property name="retryTemplate">
            <bean class="org.springframework.retry.support.RetryTemplate">
                <property name="backOffPolicy">
                    <bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
                        <property name="initialInterval" value="2000" />    
                        <property name="multiplier" value="2" />            
                        <property name="maxInterval" value="30000"/>        
                    </bean>
                </property>
                <property name="retryPolicy">
                    <bean class="org.springframework.retry.policy.SimpleRetryPolicy">
                        <property name="maxAttempts" value="3"/>
                    </bean>
                </property>
            </bean>
        </property>
        <property name="recoveryCallback">
            <bean class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
                <constructor-arg ref="defaultErrorChannel"/>
            </bean>
        </property>
    </bean>

    <bean id="custSyncResponseHandler" class="com.uscs.crm.integration.handler.CustSyncResponseHandler"></bean>
    <int:chain input-channel="defaultErrorChannel" output-channel="replySyncCustomers"> 
        <int:service-activator id="mailMessageActivator" expression="@mailHandler.process(payload)" />
        <int:header-enricher>
            <int:header name="ERROR_ID" expression="T(java.lang.System).currentTimeMillis()"/>
        </int:header-enricher>          
        <int-amqp:outbound-gateway
            exchange-name="error-responses-exchange"
            routing-key-expression="'error.response.'+headers.ERROR_ID"
            amqp-template="amqpTemplate" />
        <!-- Will this service-activator return a response to the caller (int:gateway) using channel `replySyncCustomers`? -->  
        <int:service-activator id="custSyncResponseActivator" expression="@custSyncResponseHandler.process(payload)" />             
    </int:chain>        

    <int-amqp:inbound-gateway queue-names="error-responses" request-channel="errorResponses"  
            connection-factory="rabbitConnectionFactory" acknowledge-mode="AUTO" />

    <int-mail:outbound-channel-adapter channel="errorResponses" mail-sender="mailSender" />

    <!-- (Outbound Channel Adapter/Gateway) rabbit exchanges, queues, and bindings used by this app -->
    <rabbit:topic-exchange name="error-responses-exchange" auto-delete="false" durable="true">
        <rabbit:bindings>
            <rabbit:binding queue="error-responses" pattern="error.response.*"/>
        </rabbit:bindings>
    </rabbit:topic-exchange>
    <rabbit:queue name="error-responses" auto-delete="false" durable="true"/>          
服务激活器配置

    <int:channel id="defaultErrorChannel"/>
    <int:channel id="errorResponses"/>

    <!-- 
      ExponentialBackOffPolicy.multipler is applied to wait time over each retry attempt
      with a ExponentialBackOffPolicy.maximum configured.        
    -->
    <bean id="retryWithBackoffAdviceSession" class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
        <property name="retryTemplate">
            <bean class="org.springframework.retry.support.RetryTemplate">
                <property name="backOffPolicy">
                    <bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
                        <property name="initialInterval" value="2000" />    
                        <property name="multiplier" value="2" />            
                        <property name="maxInterval" value="30000"/>        
                    </bean>
                </property>
                <property name="retryPolicy">
                    <bean class="org.springframework.retry.policy.SimpleRetryPolicy">
                        <property name="maxAttempts" value="3"/>
                    </bean>
                </property>
            </bean>
        </property>
        <property name="recoveryCallback">
            <bean class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
                <constructor-arg ref="defaultErrorChannel"/>
            </bean>
        </property>
    </bean>

    <bean id="custSyncResponseHandler" class="com.uscs.crm.integration.handler.CustSyncResponseHandler"></bean>
    <int:chain input-channel="defaultErrorChannel" output-channel="replySyncCustomers"> 
        <int:service-activator id="mailMessageActivator" expression="@mailHandler.process(payload)" />
        <int:header-enricher>
            <int:header name="ERROR_ID" expression="T(java.lang.System).currentTimeMillis()"/>
        </int:header-enricher>          
        <int-amqp:outbound-gateway
            exchange-name="error-responses-exchange"
            routing-key-expression="'error.response.'+headers.ERROR_ID"
            amqp-template="amqpTemplate" />
        <!-- Will this service-activator return a response to the caller (int:gateway) using channel `replySyncCustomers`? -->  
        <int:service-activator id="custSyncResponseActivator" expression="@custSyncResponseHandler.process(payload)" />             
    </int:chain>        

    <int-amqp:inbound-gateway queue-names="error-responses" request-channel="errorResponses"  
            connection-factory="rabbitConnectionFactory" acknowledge-mode="AUTO" />

    <int-mail:outbound-channel-adapter channel="errorResponses" mail-sender="mailSender" />

    <!-- (Outbound Channel Adapter/Gateway) rabbit exchanges, queues, and bindings used by this app -->
    <rabbit:topic-exchange name="error-responses-exchange" auto-delete="false" durable="true">
        <rabbit:bindings>
            <rabbit:binding queue="error-responses" pattern="error.response.*"/>
        </rabbit:bindings>
    </rabbit:topic-exchange>
    <rabbit:queue name="error-responses" auto-delete="false" durable="true"/>          
使用SpEL引用
#root
上下文来检索
错误消息
,而不是默认值,默认值为
MessaginException
有效负载
),并将其传递给POJO上的我的
进程
方法

    <bean id="custSyncResponseHandler" class="com.uscs.crm.integration.handler.CustSyncResponseHandler" />        
    <int:chain id="errorGatewayResponseChain" input-channel="defaultErrorChannel" output-channel="replySyncCustomers">
        <int:service-activator id="custSyncResponseActivator" expression="@custSyncResponseHandler.process(#root)" />
    </int:chain>

我看不出有什么理由在那里引入AMQP中间件复杂性,只是为了最终发送电子邮件

您只需要
,将端点作为订阅服务器

第一个是单向电子邮件发送
,第二个是
custSyncResponseActivator
,用于向您的
回复内容


你可以在Spring集成中找到更多关于这个问题的信息。

啊,当然了。这完全有道理。我将尝试一下,并让您知道它是如何工作的。我为
服务激活器创建了一个
,需要添加回
回复频道
标题属性:
。当我这样做时,我陷入了一个无限循环,但我看到响应被传递到
replycustsynccusters
频道。
出站网关
似乎没有使用回复。最后,我在客户端上收到一个
StackOverflowerError
。您应该基于
ErrorMessage.payload.getFailedMessage()
构建自定义回复消息。特别是利用其
标题
,您可以在
customerGateway的
临时回复频道
中找到
回复频道
网关上的
回复频道
使用
回复频道
向网关发送回复。也回答了这个问题:非常感谢。这真的帮了大忙。我能让它工作。在这里发布我的实现,以便它可以帮助其他人。
    <bean id="custSyncResponseHandler" class="com.uscs.crm.integration.handler.CustSyncResponseHandler" />        
    <int:chain id="errorGatewayResponseChain" input-channel="defaultErrorChannel" output-channel="replySyncCustomers">
        <int:service-activator id="custSyncResponseActivator" expression="@custSyncResponseHandler.process(#root)" />
    </int:chain>