使用 http-client 处理器将 http 请求 header 从 Spring 传递到 Rest API

Passing http request header to RestAPI from SpringXD using http-client processor

我正在尝试从我的 http-client 处理器模块中休息 api。 我想知道如何将请求 header 发送到我试图点击的 url。 没有请求 header 我收到 500 内部服务器错误。

mappedRequestHeaders 选项对传递 header 有用吗,有人可以举个例子吗。

下面是我的流的样子:

jms --destination= | http-client --url='''https://hostname:11210/cards/accounts?eName=John%20Smith&caFSix=426600&caLF=1234''' --httpMethod=GET | log

是的,假设你的 header 是 x-foo,将 http-client 处理器的 mappedRequestHeaders 属性 设置为 "HTTP_REQUEST_HEADERS, x-foo"

然后,如果入站 JMS 消息具有 header x-foo=bar,它将映射到 http-client.

这假定您正在使用本地或兔子消息总线;对于 redis,您必须配置总线以通过您的 header。

如果入站 JMS 消息没有 header,您将需要自定义处理器(或自定义 http-client)以使用 <header-enricher/> 添加 header.

编辑:

您可以使用 redis,但如果您希望它们遍历总线,则需要将您的 header 名称添加到 redis 的 servers.yml 配置中:

xd:
  messagebus:
    redis:
      headers:   

但是,如果您直接在自定义 http-client 中添加 header-enricher,他们将不需要通过总线。

您可以使用 json 路径从您的 JMS 消息中提取内容。如果您还需要更改有效负载,您可能会发现使用自定义转换器创建消息更容易。

Message<?> transform(Message<String> msg) {

   return MessageBuilder.withPayload(newPayload)
             .copyHeaders(msg)
             .setHeader("accept", "...")
             .setHeader(...)
             . ...
             .build();
}

编辑#2:

我刚刚测试过它,对我来说效果很好...

<header-enricher input-channel="input" output-channel="toHttp">
    <header name="foo" value="bar" />
</header-enricher>

<channel id="toHttp" />

<int-http:outbound-gateway id='http-client'
    request-channel='toHttp' url-expression="${url}" http-method="${httpMethod}"
    expected-response-type='java.lang.String' charset='${charset}'
    reply-timeout='${replyTimeout}' reply-channel='output'
    mapped-request-headers="${mappedRequestHeaders}"
    mapped-response-headers="${mappedResponseHeaders}">
</int-http:outbound-gateway>

<channel id="output" />
<channel id="input" />

有了这个流定义...

xd:>stream create ticktock --definition "time --fixedDelay=5 | http-client --url='''http://localhost:8080/http/receiveGateway''' --mappedRequestHeaders=HTTP_REQUEST_HEADERS,foo | log --expression=#root" --deploy

...这些结果...

18:02:20,284  INFO task-scheduler-3 sink.ticktock - GenericMessage [payload=2015-02-02 18:02:20 from the other side, headers={Server=Apache-Coyote/1.1, foo=bar, connection=keep-alive, id=8a444177-b96d-70c3-58e7-d92067d6b18e, Content-Length=39, contentType=text/plain, http_statusCode=200, Date=1422918140000, timestamp=1422918140284}]
18:02:25,292  INFO task-scheduler-3 sink.ticktock - GenericMessage [payload=2015-02-02 18:02:25 from the other side, headers={Server=Apache-Coyote/1.1, foo=bar, connection=keep-alive, id=d62b46ed-dcc7-6dd0-35ea-b7b988c4f2f1, Content-Length=39, contentType=text/plain, http_statusCode=200, Date=1422918145000, timestamp=1422918145292}]

如您所见,foo=bar 出现在最后一条消息中。

现在,在 HTTP 消息中,默认情况下,user-defined header 以 X- 为前缀,因此 foo header 显示为X-foo: bar 在 HTTP 中。

为了抑制 X-,您需要对 http-client...

进行另一次调整
<header-enricher input-channel="input" output-channel="toHttp">
    <header name="foo" value="bar" />
</header-enricher>

<channel id="toHttp" />

<int-http:outbound-gateway id='http-client'
    request-channel='toHttp' url-expression="${url}" http-method="${httpMethod}"
    expected-response-type='java.lang.String' charset='${charset}'
    reply-timeout='${replyTimeout}' reply-channel='output'
    header-mapper="mapper">
</int-http:outbound-gateway>

<beans:bean id="mapper" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper">
    <beans:property name="userDefinedHeaderPrefix" value="" />
    <beans:property name="outboundHeaderNames" value="${mappedRequestHeaders}" />
    <beans:property name="inboundHeaderNames" value="${mappedResponseHeaders}" />
</beans:bean>

<channel id="output" />
<channel id="input" />

@Gary 按照你的建议,我确实创建了一个带有 header-enricher 的自定义 http-client,如下所示:

<int-http:outbound-gateway id='http-client'
            request-channel='headerenricheroutput' url-expression="${url}" http-method="${httpMethod}"
            expected-response-type='java.lang.String' charset='${charset}'
            reply-timeout='${replyTimeout}' reply-channel='output'
            mapped-request-headers="${mappedRequestHeaders}"
            mapped-response-headers="${mappedResponseHeaders}">
    </int-http:outbound-gateway>
    <channel id="output" />
    <channel id="headerenricheroutput" />
    <header-enricher input-channel="input" output-channel="headerenricheroutput">
            <header name="User-Agent" value="Shred"/>
            <header name="Api-Key" value="AbCdEFg1HiJ23klMnopQrS4U"/>
            <header name="Accept" value="application/json"/>
    </header-enricher>

    <channel id="input" />

我创建了一个流:stream create --name abc--definition "jms --destination=myQueue| http-client --url='''https://host:port/cards/accounts?eName=John%20Smith&cardFS=426600&cardLF=1234''' --mappedRequestHeaders=HTTP_REQUEST_HEADERS,User-Agent,Api-Key,Accept --httpMethod=GET | log" --deploy

但我仍然无法将 header 传递给 URL。你能给我指出正确的方向吗?

同时,为了得到我的 API 的回复,我创建了一个 groovy 脚本来调用上面的 URL 和 header 我是能够做到。也许有人会发现它有用,所以张贴它。 groovy 脚本是:

def json = "https://host:11210/credit/accounts?eName=John%20Smith&cardFS=426600&cardLF=1234".toURL().getText(requestProperties:['User-Agent': 'Shred', 'Api-Key': 'abc', Accept: 'application/json'])

流看起来像:

jms --destination=tiki | transform --script=transform.groovy | log

我仍然无法弄清楚 http-client 需要做什么。