Spring Integration中的Http Outbound Gateway错误处理

时间:2018-07-02 12:35:27

标签: java spring spring-integration

我试图了解Spring Integration应该如何处理错误。我发现documentation关于errorChannel,我尝试使用它,但未捕获到异常。

这是我的HTTP出站网关:

<int-http:outbound-gateway id="orderRequestHttpGateway"
                               request-channel="orders-channel"
                               url="${url}"
                               http-method="POST"
                               expected-response-type="java.lang.String"
                               reply-timeout='5000'
                               reply-channel='pushed-channel'
                               charset="UTF-8">
</int-http:outbound-gateway>

我不知道应该在哪里捕获该组件引发的异常(例如500 HTTP错误)

该路由由poller开始。我尝试添加error-channel属性:

<int:inbound-channel-adapter channel="orders-trigger-channel" expression="''">
        <int:poller fixed-delay="${poller}" error-channel="errorChannel"/>
</int:inbound-channel-adapter>

我尝试使用自定义错误通道。我还尝试覆盖现有的errorChannel:

<int:channel id="errorChannel"/>
<int:outbound-channel-adapter id="errorChannelHandler"
                               ref="errorManager"
                               method="foo"
                               channel="errorChannel"/>

到目前为止,我一直收到MessageHandlingException,我无法抓住他们来正确处理它们。

2 个答案:

答案 0 :(得分:1)

您只能在调用者线程中或拥有try...catch的地方捕获异常-Spring Integration与纯Java没什么不同:只要有try...catch,我们就捕获异常。 / p>

根据您的描述,error-channel="errorChannel"上的<poller>是行之有效的方法,如果您没有其他向下游移动的线程,则这样的MessageHandlingException实际上会被扔到轮询并包装到ErrorMessage中,然后发送到配置的errorChannel

这是一个MessageHandlingException,因为我们在Spring Integration中处理Messaging,并且这样的异常包含一些上下文以及有关流和失败消息的重要信息。您的500 HTTP error只是该消息中的cause。因此,当您捕获并处理ErrorMessage时,应查看其堆栈跟踪以分析信息。

另一方面,您可以通过ExpressionEvaluatingRequestHandlerAdviceRequestHandlerRetryAdvicehttps://docs.spring.io/spring-integration/docs/5.0.6.RELEASE/reference/html/messaging-endpoints-chapter.html#message-handler-advice-chain

来缩小错误处理的范围。

答案 1 :(得分:0)

Int-http:outbound-gateway 默认具有错误处理程序,您可以使用此错误处理程序来处理出站错误。在您的示例中,将error-handler添加到int-http:outbound-gateway,其示例名称为errorHandler类名,如下所示:

<int-http:outbound-gateway id="orderRequestHttpGateway"
                               request-channel="orders-channel"
                               url="${url}"
                               http-method="POST"
                               expected-response-type="java.lang.String"
                               reply-timeout='5000'
                               reply-channel='pushed-channel'
                               charset="UTF-8"
                               error-handler="nameOfErrorHandler">
</int-http:outbound-gateway>

然后使用nameOfErrorHandler创建新的类,该类扩展了 DefaultResponseErrorHandler ,如下所示

@Component("nameOfErrorHandler")
public class NameOfErrorHandler extends DefaultResponseErrorHandler {
    public NameOfErrorHandler() {
    }

    public void handleError(ClientHttpResponse response) throws IOException {

        if (response.getStatusCode() == HttpStatus.BAD_REQUEST) {
            throw new AccessDeniedException("Custom Message");
        } else if (response.getStatusCode() == HttpStatus.FORBIDDEN) {
            throw new AccessDeniedException("Custom Message");
        } else if (response.getStatusCode() == HttpStatus.NOT_ACCEPTABLE) {
            throw new ChannelsLimitExceededException("Custom Message");
        } else if (response.getStatusCode() == HttpStatus.PROXY_AUTHENTICATION_REQUIRED) {
            throw new PerTransactionLimitExceeded("Custom Message");
        } else if (response.getStatusCode() == HttpStatus.REQUEST_TIMEOUT) {
            throw new DailyLimitExceededException("Custom Message");
        } else if (response.getStatusCode() == HttpStatus.CONFLICT) {
            throw new MonthlyLimitExceeded("Custom Message");
        } else if (response.getStatusCode() == HttpStatus.GONE) {
            throw new DuplicateReqIdException("Custom Message");
        } else {
            throw new AccessInternalException("Internal server error");
        }
    }
}

注意:这一切都引发了新的异常,这些异常是由链中定义的第一个错误通道捕获的