如何使用表达式通知或错误通道处理Spring Integration异常?
Spring Integration XML配置异常处理问题解答
我是Spring Integration新手,需基于XML配置实现异常处理,现有如下配置代码:
<int:chain id="sample-chain" input-channel="callTestChannel" output-channel="testResponseChannel"> <int:header-enricher> <int:header name="Content-Type" value="application/json"/> <int:header name="Accept" value="application/json"/> </int:header-enricher> <int-http:outbound-gateway id="testGateway" url-expression="headers.externalUrl" http-method="GET" expected-response-type="com.example.test.TestProject" charset="UTF-8" request-factory="httpComponentClientRequestFactory" mapped-request-headers="Content-Type,Accept" reply-timeout="5000"> <int-http:uri-variable name="testId" expression="payload" /> <int-http:request-handler-advice-chain> <bean class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice"> <property name="recoveryCallback"> <bean class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer"> <constructor-arg ref="retryErrorChannel" /> </bean> </property> <property name="retryTemplate" ref="retryLoadTemplate" /> </bean> </int-http:request-handler-advice-chain> </int-http:outbound-gateway> <int:transformer ref="fetchDetailsTransformer" method="processServiceDetails" /> </int:chain> <int:channel id="retryErrorChannel"/> <int:transformer input-channel="retryErrorChannel" output-channel="markErrorChannel" expression="payload.getFailedMessage()"/> <int:transformer input-channel="markErrorChannel" output-channel="tmsResponseChannel" expression="'this Id :' + payload + ' could not find.'"/> <bean id="retryLoadTemplate" class="org.springframework.retry.support.RetryTemplate"> <property name="retryPolicy"> <bean class="org.springframework.retry.policy.SimpleRetryPolicy"> <property name="maxAttempts" value="4" /> </bean> </property> <property name="backOffPolicy"> <bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy"> <property name="initialInterval" value="1000" /> <property name="multiplier" value="5" /> </bean> </property> </bean>
问题解答
1. 如何创建错误通道以处理不同类型的异常?
可以通过ErrorMessageTypeRouter按异常类型路由到不同的处理通道,实现差异化异常处理:
- 先定义对应不同异常类型的错误通道:
<int:channel id="httpErrorChannel"/> <int:channel id="timeoutErrorChannel"/> <int:channel id="genericErrorChannel"/>
- 配置类型路由器,根据异常类型分发消息:
<int:router input-channel="retryErrorChannel" expression="payload.cause.class"> <int:mapping value="org.springframework.web.client.HttpClientErrorException" channel="httpErrorChannel"/> <int:mapping value="org.springframework.web.client.ResourceAccessException" channel="timeoutErrorChannel"/> <int:mapping value="java.lang.Exception" channel="genericErrorChannel"/> </int:router>
- 为每个通道配置针对性的处理逻辑:
<int:transformer input-channel="httpErrorChannel" output-channel="tmsResponseChannel" expression="'HTTP Error for Id:' + payload.failedMessage.payload + ', Status: ' + payload.cause.statusCode"/> <int:transformer input-channel="timeoutErrorChannel" output-channel="tmsResponseChannel" expression="'Timeout occurred for Id:' + payload.failedMessage.payload"/> <int:transformer input-channel="genericErrorChannel" output-channel="tmsResponseChannel" expression="'Unexpected error for Id:' + payload.failedMessage.payload + ', Message: ' + payload.cause.message"/>
说明:
ErrorMessage的payload是MessagingException,payload.cause就是实际抛出的异常对象,通过payload.cause.class获取异常类型完成路由。
2. 是否可通过int-http:outbound-gateway的属性实现异常处理?
可以,int-http:outbound-gateway提供了两个核心属性用于异常处理:
error-handler:指定自定义的ResponseErrorHandlerBean,用来处理HTTP响应错误(如4xx、5xx状态码)。示例:
<bean id="customErrorHandler" class="org.springframework.web.client.DefaultResponseErrorHandler"> <!-- 可重写hasError/handleError方法自定义错误判断逻辑,比如允许特定4xx状态码不抛出异常 --> </bean> <int-http:outbound-gateway ... error-handler="customErrorHandler"> <!-- 其他原有配置 --> </int-http:outbound-gateway>
reply-timeout:你已配置该属性,超时会抛出ResourceAccessException,可被重试通知或错误通道捕获处理。
另外,网关抛出的异常会被调用链的错误处理机制捕获,若未配置自定义错误通道,会默认转发到全局errorChannel。
3. 表达式通知的XML配置及更简便的异常处理方式
表达式通知(ExpressionEvaluatingRequestHandlerAdvice)XML配置
该通知无需重试逻辑,可直接在异常时执行表达式逻辑,配置示例:
<int-http:request-handler-advice-chain> <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice"> <!-- 异常触发时执行的表达式,将错误信息发送到指定通道 --> <property name="onFailureExpression" value="T(org.springframework.integration.support.MessageBuilder).withPayload(payload).setHeader('errorMsg', exception.message).sendTo('customErrorChannel')"/> <!-- 设置为true则异常不会向上传播,避免中断整个链 --> <property name="trapException" value="true"/> <!-- 可选:配置onSuccessExpression处理成功场景 --> </bean> </int-http:request-handler-advice-chain>
更简便的异常处理方式
- 全局错误通道:Spring Integration默认提供
errorChannel,所有未被捕获的异常都会发送到这里。只需配置一个服务激活器统一处理:
<int:service-activator input-channel="errorChannel" ref="globalErrorHandler" method="handleError"/> <bean id="globalErrorHandler" class="com.example.GlobalErrorHandler"/>
在GlobalErrorHandler类中编写handleError(ErrorMessage errorMessage)方法,根据异常类型做统一处理。
- 链级错误通道:直接给
<int:chain>配置error-channel属性,链内所有组件抛出的异常都会转发到该通道,无需逐个组件配置通知:
<int:chain id="sample-chain" input-channel="callTestChannel" output-channel="testResponseChannel" error-channel="chainErrorChannel"> <!-- 链内原有组件 --> </int:chain>
后续只需配置chainErrorChannel的处理逻辑即可,适合整个调用链的统一异常处理。
内容的提问来源于stack exchange,提问作者KeepItSimple
相关产品推荐
相关产品推荐

