使用http-client处理器从Spring将http请求标头传递给Rest API

时间:2015-01-23 21:27:25

标签: http-headers spring-xd

我正试图从我的http客户端处理器模块中找到一个rest api。 我想知道如何将请求标头发送到我想要的网址。 如果没有请求标头,我会收到500内部服务器错误。

对于传递标题,mappedRequestHeaders选项是否有用,请有人举个例子。

以下是我的信息流的样子:

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

2 个答案:

答案 0 :(得分:1)

是的,假设您的标头为x-foo,请将mappedRequestHeaders处理器的http-client属性设置为"HTTP_REQUEST_HEADERS, x-foo"

然后,如果入站JMS消息有标题x-foo=bar,则它将映射到http-client

这假设您使用的是本地或兔子消息总线;对于redis,您必须配置总线以传递标题。

如果入站JMS邮件没有标头,则需要自定义处理器(或自定义http-client)才能使用<header-enricher/>添加标头。

修改

您可以使用redis,但是如果您希望它们遍历总线,则需要将头名称添加到servers.yml config for redis:

xd:
  messagebus:
    redis:
      headers:   

但是,如果您在自定义http客户端中直接添加标题扩充器,则无需通过总线。

您可以使用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消息中,默认情况下,用户定义的标头以X-为前缀,因此foo标头在HTTP中显示为X-foo: bar

为了取消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" />

答案 1 :(得分:1)

@Gary正如您所建议的那样,我确实创建了一个带有标题扩展器的自定义http客户端,如下所示:

<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

但我仍然无法将标头传递给网址。你能指点我正确的方向。

同时,只是为了从我的API获得回复,我创建了一个groovy脚本来调用带有标题的上述URL,我能够做到这一点。也许有人会发现它很有用所以发布它。 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做些什么。