setOnFailureExpression 不适用于 #root 和 #exception [英] setOnFailureExpression not working for #root and #exception
问题描述
@Bean
public ExpressionEvaluatingRequestHandlerAdvice after() {
logger.debug("Evaluating expression advice. ");
ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
advice.setTrapException(true);
advice.setOnFailureExpressionString("#root");
advice.setSuccessChannel(rtwSourceDeletionChannel());
advice.setFailureChannel(rtwFtpFailureHandleChannel());
advice.setPropagateEvaluationFailures(true);
return advice;
}
@Bean
public IntegrationFlow rtwFtpFailureHandlerFlow() {
return IntegrationFlows
.from(rtwFtpFailureHandleChannel())
.handle( msg -> {
// code to delete all files except source.
logger.debug("Handling Failure......");
List<String> transitPaths = (List<String>) msg.getHeaders().get(AdviceHandlerMessageHeaders.TRANSIT_PATHS);
String sourcePath = (String) msg.getHeaders().get(AdviceHandlerMessageHeaders.SOURCE);
System.out.println("payload: " + msg.getPayload());
})
.get();
}
为 #root 和 #exception 产生相同的结果,如下所示:
Produces same result for #root and #exception as below:
payload: org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice$MessageHandlingExpressionEvaluatingAdviceException: Handler Failed; nested exception is org.springframework.messaging.MessageHandlingException: error occurred in message handler [rtwFtpOutboundHandler]; nested exception is org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is org.springframework.integration.util.PoolItemNotAvailableException: Failed to obtain pooled item, failedMessage=GenericMessage [payload=sample.pdf, headers={file_name=sample.pdf, TRANSIT_PATHS=[\\localhost\atala-capture-upload, sample.tif], SOURCE=\\localhost\atala-capture-upload, file_originalFile=\\localhost\atala-capture-upload\sample.tif, id=746728a4-9b9e-847f-6c2c-29aa8a4a5fd6, file_relativePath=sample.tif, timestamp=1549922458296}], failedMessage=GenericMessage [payload=sample.pdf, headers={file_name=sample.pdf, TRANSIT_PATHS=[\\localhost\atala-capture-upload, sample.tif], SOURCE=\\localhost\atala-capture-upload, file_originalFile=\\localhost\atala-capture-upload\sample.tif, id=746728a4-9b9e-847f-6c2c-29aa8a4a5fd6, file_relativePath=sample.tif, timestamp=1549922458296}]
推荐答案
按预期工作.
逻辑是这样的:
try {
evalResult = this.onFailureExpression.getValue(prepareEvaluationContextToUse(exception), message);
}
catch (Exception e) {
evalResult = e;
logger.error("Failure expression evaluation failed for " + message + ": " + e.getMessage());
}
DestinationResolver<MessageChannel> channelResolver = getChannelResolver();
if (this.failureChannel == null && this.failureChannelName != null && channelResolver != null) {
this.failureChannel = channelResolver.resolveDestination(this.failureChannelName);
}
if (evalResult != null && this.failureChannel != null) {
MessagingException messagingException =
new MessageHandlingExpressionEvaluatingAdviceException(message, "Handler Failed",
unwrapThrowableIfNecessary(exception), evalResult);
ErrorMessage errorMessage = new ErrorMessage(messagingException);
this.messagingTemplate.send(this.failureChannel, errorMessage);
}
onFailureExpression
的计算结果作为属性添加到MessageHandlingExpressionEvaluatingAdviceException
.并且这个异常被包装到 ErrorMessage
中发送到配置的 failureChannel
.
The evaluation result of the onFailureExpression
is added to the MessageHandlingExpressionEvaluatingAdviceException
as property. And this exception is wrapped to the ErrorMessage
to be sent to the configured failureChannel
.
因此,到目前为止,您的代码是正确的,除非您错过了这样一个事实,即您在 rtwFtpFailureHandlerFlow
中处理的消息的 payload
正是提到的 MessageHandlingExpressionEvaluatingAdviceException代码>.要访问表达式的结果,您需要将
payload
转换为该异常并调用其 getEvaluationResult()
.另一方面,您甚至不需要任何复杂的表达式,因为请求消息可用作此异常的 failedMessage
.此外,真正的失败在于此异常的原因.
So, your code is correct so far, unless you are missing the fact that payload
of the message you process in that rtwFtpFailureHandlerFlow
is exactly the mentioned MessageHandlingExpressionEvaluatingAdviceException
. To get access to the result of your expression, you need to cast a payload
to this exception and call its getEvaluationResult()
. On the other hand you even don't need to have have any complex expression since a request message is available as a failedMessage
of this exception. Plus the real failure is in the cause of this exception.
See docs for more info: https://docs.spring.io/spring-integration/docs/current/reference/html/messaging-endpoints-chapter.html#expression-advice
这篇关于setOnFailureExpression 不适用于 #root 和 #exception的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!