Spring integration: preserve http error code and body in response

允我心安 提交于 2019-12-12 04:38:55

问题


I have an inbound http gateway whose incoming message is passed to an outbound http gateway (using integration java dsl).

When the outbound gateway response has http status 200, the outbound response goes back to the caller of the inbound gateway as expected.

But when the outbound gateway responds with specific client errors like 423 locked or 403 forbidden, the caller of the inbound gateway receives 500 and a body message that contains an exception as String.

I understand that this is because SI handles outbound http errors as exceptions. But in my case I need to pass through the error status and the response body that comes with the outbound response back to the caller of the inbound gateway, for the specific error codes. How do I do that?


回答1:


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



来源:https://stackoverflow.com/questions/45627072/spring-integration-preserve-http-error-code-and-body-in-response

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!