Spring 集成 HTTP 出站网关 header 不转发连续请求

Spring Integration HTTP Outbound Gateway header not forwarder on a consecutive request

我正在努力处理以下流程:

.enrichHeaders(h -> h.headerFunction("ocp-apim-subscription-key", m ->
        "xxx"))
.handle(Http.outboundGateway("https://northeurope.api.cognitive.microsoft.com/vision/v3" +
        ".0/read/analyzeResults/abc")
        .mappedRequestHeaders("ocp-apim-subscription-key")
        .httpMethod(HttpMethod.GET))
.enrichHeaders(h -> h.headerFunction("ocp-apim-subscription-key", m ->
        "xxx"))
.handle(Http.outboundGateway("https://northeurope.api.cognitive.microsoft.com/vision/v3" +
        ".0/read/analyzeResults/def")
        .mappedRequestHeaders("ocp-apim-subscription-key")
        .httpMethod(HttpMethod.GET))

第一个请求提交正确,我得到了结果,第二个请求我得到 401 UNAUTHORIZED 这意味着,ocp-apim-subscription-key 不包括在内。我试过没有第二个浓缩步骤,因为我认为 headers 不会被清除,但它也没有改变任何东西。

知道我可能做错了什么吗?我是否需要以不同方式配置 header 映射器?

这是调试的输出,它清楚地表明包含了 header:

17:45:31.468 [main] DEBUG org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler - bean 'ocrDocument.http:outbound-gateway#2' for component 'ocrDocument.org.springframework.integration.config.ConsumerEndpointFactoryBean#3'; defined in: 'processing.OCRIntegrationFlow'; from source: 'bean method ocrDocument' received message: GenericMessage [payload=<200,[Transfer-Encoding:"chunked", Content-Type:"application/json; charset=utf-8", x-envoy-upstream-service-time:"25", CSP-Billing-Usage:"CognitiveServices.ComputerVision.Transaction=1", Strict-Transport-Security:"max-age=31536000; includeSubDomains; preload", x-content-type-options:"nosniff", Date:"Mon, 31 Aug 2020 15:45:31 GMT"]>, headers={Transfer-Encoding=chunked, ocp-apim-subscription-key=xxx, id=11fa4a77-d97a-772b-69b6-059de29ef808, contentType=application/json;charset=utf-8, http_statusCode=200 OK, Date=1598888731000, timestamp=1598888731467}]

更新 我用 wireshark 记录了一个 session(切换到 http 而不是 https,因为我无法让它工作)。似乎在第二个请求中 subscription-key 没有传播。由于某种原因,第二个中包含了更多 header。

第一个

第二个

好的。我看看哪里出了问题:

private HttpEntity<?> createHttpEntityFromPayload(Message<?> message, HttpMethod httpMethod) {
Object payload = message.getPayload();
if (payload instanceof HttpEntity<?>) {
    // payload is already an HttpEntity, just return it as-is
    return (HttpEntity<?>) payload;
}
HttpHeaders httpHeaders = mapHeaders(message);

由于您将 ResponseEntity 从第一次调用传播到第二次调用,因此确实没有任何 headers 映射,因为我们只是不在 [=12= 中执行该逻辑] 并按原样使用提供的 HttpEntity

我们无法假设您想用它做什么,但由于您提供了整个实体,我们只是不改变它并按原样执行请求。

为了解决这个问题,我建议在第二次调用之前包含一些简单的 .transform((p) -> "") 以避免某些 HTTP 实体假设。

是的,如果 ocp-apim-subscription-key 的值相同,则不需要第二个 header enricher。

我们可能需要改进有关此事的文档,并解释此组件中如何处理请求消息。欢迎提出 GH 问题!