We call this scenario as HTTP Proxy and have some test-case on the matter: https://github.com/spring-projects/spring-integration/blob/master/spring-integration-http/src/test/java/org/springframework/integration/http/dsl/HttpDslTests.java
I've just done some investigation and here is what you need:
IntegrationFlows
.from(Http.inboundGateway("/service")
.requestMapping(r -> r.params("name"))
.errorChannel("httpProxyErrorFlow.input"))
...
@Bean
public IntegrationFlow httpProxyErrorFlow() {
return f -> f
.transform(Throwable::getCause)
.<HttpClientErrorException>handle((p, h) ->
MessageBuilder.withPayload(p.getResponseBodyAsString())
.setHeader(HttpHeaders.STATUS_CODE, p.getStatusCode())
.build());
}
We have to handle downstream errors on the Inbound Gateway level. For this purpose Spring Integration suggest the errorChannel
functionality.
That httpProxyErrorFlow
provides some logic on the matter. First of all we know that the message for the errorChannel
is ErrorMessage
and its payload
is MessagingException
- as a result of wrapping HttpClientErrorException
in the HttpRequestExecutingMessageHandler
. So, with the .transform()
we drill down to the desired exception and in the .handle()
we build a new message based on the HttpClientErrorException
content.
The HttpRequestHandlingMessagingGateway
is able to process such a message properly and set a desired status code to the response:
protected final Object setupResponseAndConvertReply(ServletServerHttpResponse response, Message<?> replyMessage) {
getHeaderMapper().fromHeaders(replyMessage.getHeaders(), response.getHeaders());
HttpStatus httpStatus = this.resolveHttpStatusFromHeaders(replyMessage.getHeaders());
if (httpStatus != null) {
response.setStatusCode(httpStatus);
}
http://docs.spring.io/spring-integration/docs/4.3.11.RELEASE/reference/html/http.html#http-response-statuscode