我试图了解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
,我无法抓住他们来正确处理它们。
答案 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
时,应查看其堆栈跟踪以分析信息。
另一方面,您可以通过ExpressionEvaluatingRequestHandlerAdvice
或RequestHandlerRetryAdvice
:https://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");
}
}
}
注意:这一切都引发了新的异常,这些异常是由链中定义的第一个错误通道捕获的