Rabbitmq http客户端的Spring xd问题

Rabbitmq http客户端的Spring xd问题,rabbitmq,spring-integration,spring-xd,Rabbitmq,Spring Integration,Spring Xd,我有SpringXD模块,rabbitmq作为传输。我的模块有http源http客户端处理器,它调用RESTURL 现在,当我的rest客户端抛出任何异常(如404或连接超时异常)时,消息返回http | http客户端之间的兔子队列 我的理解是,只有连接超时异常才会被放回队列,而任何其他异常或200都会将消息移动到下一个组件,即http客户端|日志。但当我尝试时,所有异常都被放回http | http客户端之间的队列 现在,我的用例是我想重试所有套接字超时/连接超时异常。我想将任何其他系统异常

我有SpringXD模块,rabbitmq作为传输。我的模块有http源http客户端处理器,它调用RESTURL

现在,当我的rest客户端抛出任何异常(如404或连接超时异常)时,消息返回http | http客户端之间的兔子队列

我的理解是,只有连接超时异常才会被放回队列,而任何其他异常或200都会将消息移动到下一个组件,即http客户端|日志。但当我尝试时,所有异常都被放回http | http客户端之间的队列


现在,我的用例是我想重试所有套接字超时/连接超时异常。我想将任何其他系统异常50x错误写入日志或文件接收器?我如何实现这一点。基本上,根据异常情况,我想路由重试和非重试异常。

只有2xx结果将进入
日志

4xx
5xx
被视为错误

您需要一个自定义的代码> HTTP客户端< />模块,以捕获您认为“OK”的异常,并将它们转发到<代码>输出< /代码>通道。类似于

<int:service-activator input-channel="input" ref="gw" />

<int:gateway request-channel="toHttp" error-channel="errors" />

<int:chain input-channel="errors" output-channel="output">
    <!-- examine payload.cause (http status code etc) and decide whether 
         to throw an exception or return the status code for sending to output -->
</int:chain>

我们尝试按照上述建议实施。它现在正在过滤4XX错误,并将有效负载发送到下一个模块。但是,这些消息在内部mq中未被确认。变更后,如果发生2XX,则不会进行确认。在更改之前,2XX确认发生得很好。5XX重试继续正常进行。请让我们知道如何克服这个问题

下面是上下文xml

<service-activator input-channel="inputX" ref="gw" />

<gateway id="gw" default-request-channel="toHttp" error-channel="errors" />

<beans:bean id="responseInterceptor" class="com.batch.httpclient.ResponseInterceptor">
</beans:bean>

<chain input-channel="errors" output-channel="output">
<transformer ref="responseInterceptor"  />
</chain>


<int-http:outbound-gateway id='batch-http'  header-mapper="headerMapper"
                           request-channel='toHttp' url-expression="${url}" http-method="${httpMethod}"
                           expected-response-type='java.lang.String' charset='${charset}'
                           reply-timeout='${replyTimeout}' reply-channel='output'>
</int-http:outbound-gateway>

<beans:bean id="headerMapper" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper"
            factory-method="outboundMapper">
    <beans:property name="outboundHeaderNames" value="*"/>
    <beans:property name="userDefinedHeaderPrefix" value=""/>
</beans:bean>

<channel id="output" />
<channel id="input" />
<channel id="inputX" />
<channel id="toHttp" />


ResponseInterceptor的Java代码如下所示-

public Message<String> transform(ErrorMessage errorMessage) {


        if(null != errorMessage && null != errorMessage.getPayload() && null != errorMessage.getPayload().getCause()
                && null != errorMessage.getPayload().getCause().getMessage()){
            String rootCause = errorMessage.getPayload().getCause().getMessage();
            //check if the error message contains 400 or 404 http code.
            if(rootCause.contains("400") || rootCause.contains("404")){
                return MessageBuilder.withPayload(errorMessage.getPayload().getCause().getMessage())
                        .copyHeaders(errorMessage.getHeaders())
                        .removeHeader("errorChannel")
                        .removeHeader("replyChannel")
                        .setReplyChannelName("output").setErrorChannelName(null).build();
            }

        }
        return null;
    }

}
公共消息转换(ErrorMessage ErrorMessage){
如果(null!=errorMessage&&null!=errorMessage.getPayload()&&null!=errorMessage.getPayload().getCause()
&&null!=errorMessage.getPayload().getCause().getMessage()){
字符串rootCause=errorMessage.getPayload().getCause().getMessage();
//检查错误消息是否包含400或404 http代码。
if(rootCause.contains(“400”)| | rootCause.contains(“404”)){
返回MessageBuilder.withPayload(errorMessage.getPayload().getCause().getMessage())
.copyHeaders(errorMessage.getHeaders())
.removeHeader(“错误通道”)
.removeHeader(“replyChannel”)
.setReplyChannelName(“输出”).setErrorChannelName(null).build();
}
}
返回null;
}
}

Hi Gary,我们尝试了以下方法,但我们遇到了下面所述的问题。不要将澄清作为另一个答案,请编辑您的问题。问题是您将null返回到网关,它将永远等待答复。向网关添加
defaultreply timeout=“0”
,以在过滤后释放线程。
public Message<String> transform(ErrorMessage errorMessage) {


        if(null != errorMessage && null != errorMessage.getPayload() && null != errorMessage.getPayload().getCause()
                && null != errorMessage.getPayload().getCause().getMessage()){
            String rootCause = errorMessage.getPayload().getCause().getMessage();
            //check if the error message contains 400 or 404 http code.
            if(rootCause.contains("400") || rootCause.contains("404")){
                return MessageBuilder.withPayload(errorMessage.getPayload().getCause().getMessage())
                        .copyHeaders(errorMessage.getHeaders())
                        .removeHeader("errorChannel")
                        .removeHeader("replyChannel")
                        .setReplyChannelName("output").setErrorChannelName(null).build();
            }

        }
        return null;
    }

}