0

我有一个入站 http 网关,其传入消息被传递到出站 http 网关(使用集成 java dsl)。

当出站网关响应的 http 状态为 200 时,出站响应按预期返回到入站网关的调用方。

但是,当出站网关响应特定客户端错误(如 423 锁定或 403 禁止)时,入站网关的调用方会收到 500 和包含异常字符串的正文消息。

我知道这是因为 SI 将出站 http 错误作为异常处理。但在我的情况下,我需要将错误状态出站响应附带的响应正文传递回入站网关的调用者,以获得特定的错误代码。我怎么做?

4

1 回答 1

1

我们将此场景称为 HTTP 代理,并对此进行了一些测试:https ://github.com/spring-projects/spring-integration/blob/master/spring-integration-http/src/test/java/org /springframework/integration/http/dsl/HttpDslTests.java

我刚刚做了一些调查,这就是你需要的:

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());
}

我们必须在入站网关级别处理下游错误。为此,Spring Integration 建议了该errorChannel功能。

httpProxyErrorFlow为此事提供了一些逻辑。首先,我们知道errorChannelisErrorMessage和它的消息payloadMessagingException- 作为包装HttpClientErrorExceptionHttpRequestExecutingMessageHandler. 因此,随着.transform()我们深入到所需的异常并在其中.handle()我们基于内容构建新消息HttpClientErrorException

HttpRequestHandlingMessagingGateway能够正确处理此类消息并为响应设置所需的状态代码:

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

于 2017-08-11T17:39:09.567 回答