How to get the response body spring integration advice

Viewed 70

i have an outbound gateway. to handle exceptions I have added an advice chain,

@ServiceActivator(inputChannel = "channelOutbound")
    @Bean
    public HttpRequestExecutingMessageHandler outboundEpay() {
        final HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler(
                endpoint);
        handler.setExpectedResponseType(String.class);
        handler.setHttpMethod(HttpMethod.PUT);
        handler.setOutputChannelName("channelReply");
        handler.setAdviceChain(Collections.singletonList(advice()));
        return handler;
    }

 @Bean
    public Advice advice() {
        final ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
        advice.setFailureChannelName("channelAdvice");
        advice.setOnFailureExpressionString("payload");
        advice.setTrapException(true);
        return advice;
    }

when the API which is connected by the outbound gateway returns 200, everything works as expected. but when the API returns 500 status, an exception is thrown and the service activator connected to "channelAdvice" gets that. but I want to get the response body returned by the API along with 500 status. What should I do to get that response in advice?

@ServiceActivator(inputChannel = "channelAdvice")
    public void activatorAdvice(Message<?> message) {
//HERE
}
1 Answers

The DefaultResponseErrorHandler has a logic like this when exception is thrown in the RestTemplate:

case SERVER_ERROR:
                throw HttpServerErrorException.create(message, statusCode, statusText, headers, body, charset);

So, an HttpServerErrorException thrown by the HttpRequestExecutingMessageHandler has a responseBody property. That's the way for you to extract that body for error from a ErrorMessage sent to your channelAdvice.

Consider to debug your activatorAdvice() method to see a content of that message argument.

The logic in the HttpRequestExecutingMessageHandler is:

catch (RestClientException e) {
        throw new MessageHandlingException(requestMessage,
                "HTTP request execution failed for URI [" + uri + "] in the [" + this + ']', e);
    }

So, that ExpressionEvaluatingRequestHandlerAdvice catches it and does this for sending an ErrorMessage :

MessagingException messagingException =
                new MessageHandlingExpressionEvaluatingAdviceException(message, "Handler Failed",
                        unwrapThrowableIfNecessary(exception), evalResult);
        ErrorMessage errorMessage = new ErrorMessage(messagingException);
        this.messagingTemplate.send(this.failureChannel, errorMessage);

Therefore ErrorMessage for your service activator contains MessageHandlingExpressionEvaluatingAdviceException as a payload and with a cause as a HttpServerErrorException.

Related