当前位置: 首页 > 知识库问答 >
问题:

Spring集成:如何将自定义 HTTP 标头添加到 HTTP 出站网关?

松鸣
2023-03-14

我正在尝试使用< code >传递一些自定义的HTTP头

我试过两种配置。第一个具有“< code > mapped-request-headers ”属性:

<int:chain input-channel="requestChannel" output-channel="replyChannel">
    <int:header-enricher>
        <int:header name="test" value="test"></int:header>
    </int:header-enricher>
    <int-http:outbound-gateway id="gateway"
        encode-uri="true" url="http://localhost:8080/webapp/service/{request}"
        http-method="GET" mapped-request-headers="test, HTTP_REQUEST_HEADERS">
        <int-http:uri-variable name="request" expression="payload"/>
    </int-http:outbound-gateway>
</int:chain>

第二个具有“头映射器”属性,具有相对DefaultHttpHeaderMapper配置:

<int:chain input-channel="requestChannel" output-channel="replyChannel">
    <int:header-enricher>
        <int:header name="test" value="test"></int:header>
    </int:header-enricher>
    <int-http:outbound-gateway id="gateway"
        encode-uri="true" url="http://localhost:8080/webapp/service/{request}"
        http-method="GET" header-mapper="headerMapper">
        <int-http:uri-variable name="request" expression="payload"/>
    </int-http:outbound-gateway>
</int:chain>

<bean id="headerMapper" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper">
    <property name="outboundHeaderNames" value="HTTP_REQUEST_HEADERS, test" />
    <property name="userDefinedHeaderPrefix" value="" />
</bean>

但在这两种情况下,远程应用程序加载的消息头如下:

GenericMessage[
    payload={},
    headers={
        http_requestMethod=GET,
        replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@4c8b7a27,
        errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@4c8b7a27,
        host=localhost: 8080,
        http_requestUrl=http://localhost:8080/webapp/service/hello,
        connection=keep-alive,
        id=3c2a21ba-b7f5-e5e9-c821-45251d406318,
        cache-control=no-cache,
        pragma=no-cache,
        user-agent=Java/1.8.0_65,
        accept=[
            text/html,
            image/gif,
            image/jpeg,
            */*;q=.2,
            */*;q=.2],
        timestamp=1469009855797
    }
]

没有我试图添加到请求消息中的“test”头的跟踪。

添加自定义标题的正确方法是什么

这也是很好的任何其他工作解决方案。

更新

按照加里的指示,我打开了调试模式。

这是一个非常有趣的事情:日志说标头[test]“将被映射”:

message sent: GenericMessage [payload=hello, headers={id=79f98422-418b-f00f-1e21-09461b1ff80c, timestamp=1469021452494}]
2016-07-20 15:53:57 DEBUG org.springframework.integration.http.support.DefaultHttpHeaderMapper.fromHeaders:402 (executor-4) - outboundHeaderNames=[test, HTTP_REQUEST_HEADERS]
2016-07-20 15:53:57 DEBUG org.springframework.integration.http.support.DefaultHttpHeaderMapper.shouldMapHeader:537 (executor-4) - headerName=[test] WILL be mapped, matched pattern=test
2016-07-20 15:53:57 DEBUG org.springframework.integration.http.support.DefaultHttpHeaderMapper.fromHeaders:420 (executor-4) - setting headerName=[X-test], value=test
2016-07-20 15:53:57 DEBUG org.springframework.http.client.support.HttpAccessor.createRequest:79 (executor-4) - Created GET request for "http://localhost:8080/webapp/service/hello"

我在服务器端实现了一个简单的过滤器,它拦截每个HTTP请求,并在日志中打印该请求的每个报头。

这就是结果:

x-test=test
cache-control=no-cache
pragma=no-cache
user-agent=Java/1.8.0_65
host=localhost:8080
accept=text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
connection=keep-alive

因此,HttpServletRequest实例上存在标头“x-test”。

但在那之后,在日志中我可以看到另一条消息(我只报告了对该上下文有意义的消息):

2016-07-20 15:53:57 DEBUG org.springframework.web.servlet.DispatcherServlet.doService:865 (http-nio-8080-exec-1) - DispatcherServlet with name 'dispatcherServer' processing GET request for [/webapp/service/hello]
2016-07-20 15:53:57 DEBUG org.springframework.integration.http.support.DefaultHttpHeaderMapper.toHeaders:436 (http-nio-8080-exec-1) - inboundHeaderNames=[Accept, Accept-Charset, Accept-Encoding, Accept-Language, Accept-Ranges, Authorization, Cache-Control, Connection, Content-Length, Content-Type, Cookie, Date, Expect, From, Host, If-Match, If-Modified-Since, If-None-Match, If-Range, If-Unmodified-Since, Max-Forwards, Pragma, Proxy-Authorization, Range, Referer, TE, Upgrade, User-Agent, Via, Warning]
2016-07-20 15:53:57 DEBUG org.springframework.integration.http.support.DefaultHttpHeaderMapper.shouldMapHeader:561 (http-nio-8080-exec-1) - headerName=[x-test] WILL NOT be mapped
2016-07-20 15:53:57 DEBUG org.springframework.integration.handler.AbstractMessageHandler.handleMessage:115 (executor-4) - ServiceActivator for [org.springframework.integration.handler.MethodInvokingMessageProcessor@6ae60a] (channelServiceActivator) received message: GenericMessage [payload={}, headers={http_requestMethod=GET, replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@565fe0d8, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@565fe0d8, host=localhost:8080, http_requestUrl=http://localhost:8080/webapp/service/hello, connection=keep-alive, id=9578f82d-7fc2-fe94-d8bf-3225ec955b22, cache-control=no-cache, pragma=no-cache, user-agent=Java/1.8.0_65, accept=[text/html, image/gif, image/jpeg, */*;q=.2, */*;q=.2], timestamp=1469022837172}]

现在日志说头“[x-test]不会被映射”。怎么可能?是因为它没有出现在< code>inboundHeaderNames中?

事实上,标题似乎在GenericMessage中“消失”了:

GenericMessage [
    payload={}, 
    headers={
        http_requestMethod=GET,
        replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@16b10fb6,
        errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@16b10fb6,
        host=localhost:8080,
        http_requestUrl=http://localhost:8080/webapp/service/hello,
        connection=keep-alive,
        id=ba2af515-9e29-4d84-d176-5b9d0d066cb0,
        cache-control=no-cache,
        pragma=no-cache,
        user-agent=Java/1.8.0_65,
        accept=[text/html,
            image/gif,
            image/jpeg,
            */*;q=.2,
            */*;q=.2],
        timestamp=1469021452542
    }
]

我不明白为什么HTTP请求中会出现这个头,但是消息通道的头中却没有。

共有2个答案

幸乐湛
2023-03-14

打开调试日志记录;您应该看到有关标题映射的消息,如下所示...

08:46:44.987 DEBUG[main]… HeaderName=[id]不会被映射

08:46:44.987调试[主]...将映射headerName=[test],匹配模式=test

08:46:44.987调试[main]…设置headerName=[X-test],值=foo

(这是您的第一个示例——默认情况下,自定义头当前使用< code>X-前缀)。

凤晨朗
2023-03-14

我已经找到了这个问题的答案。

因此,必须定义一个“头映射器”

    < li >映射< code >的< code >“inboundHeaderNames”

在我的示例中,“OUTBOUND SIDE”(客户端应用程序)的解决方案是:

<int:chain input-channel="requestChannel" output-channel="replyChannel">
    <int:header-enricher>
        <int:header name="test" value="test"></int:header>
    </int:header-enricher>
    <int-http:outbound-gateway id="gateway"
        encode-uri="true" url="http://localhost:8080/webapp/service/{request}"
        http-method="GET" header-mapper="headerMapper">
        <int-http:uri-variable name="request" expression="payload"/>
    </int-http:outbound-gateway>
</int:chain>

<bean id="headerMapper" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper">
    <property name="outboundHeaderNames" value="HTTP_REQUEST_HEADERS, test" />
    <property name="userDefinedHeaderPrefix" value="" />
</bean>

必须使用必须在“出站请求”(在本例中为“测试”)中映射的标头名称来设置“out⃣HeaderNames”

虽然“INBOUND SIDE”(接收器应用程序)的解决方案是:

<int-http:inbound-gateway id="gateway" request-channel="requestChannel"
      path="/service/**" supported-methods="GET"
      reply-channel="outputChannel" header-mapper="headerMapper">
</int-http:inbound-gateway>

<bean id="headerMapper" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper">
    <property name="inboundHeaderNames" value="*" />
</bean>

设置为“*”的“入站标头”可确保源请求的所有标头都将映射到消息标头中。

使用这种方法,我们可以将自定义头传递给HTTP请求中的任何URL,并且可以在服务器端的消息通道上下文中恢复它们。

 类似资料:
  • 我的spring集成项目配置如下: 1- 用于使用 MQ XML 消息的 JMS 消息驱动通道适配器。 2- 用于将这些 XML 消息发送到受保护的 REST 服务的 HTTP 出站网关。 3- REST服务需要在HTTP请求头中设置一个身份验证令牌。 为了完成 #3,我在出站网关前面添加了一个标头扩充器组件。 我遇到的问题是使用头中包含的令牌进行REST服务请求调用。因此,我得到了401错误。

  • 添加HTTP最简单的方法是什么。我的程序中的outboundGateway头? 我想做的是: 我首先对URL执行HTTP GET 然后我得到JSON 我提取session变量的值,并将其添加到下一个HTTP GET作为session头变量。 目前我有工作代码,但我想我可以做得更容易吗?我的实现 > 然后,该实现使用enrichHeaders方法将session变量添加到集成流消息头中 然后,该实现

  • 我正试图发送一个授权令牌,但我的服务器不知何故没有接收它。 //service.ts } //endpoint //标记过滤器

  • 问题内容: 澄清点:将自定义标头添加到我的jQuery ajax调用中没有任何问题,我想将我的自定义标头自动添加到所有ajax调用中。 如果您看看jquery $.ajax自定义http标头问题(不是我的问题),您将看到一个很好的示例,说明如何为每个ajax调用手动实现代码。 我想为所有jQuery ajax调用覆盖beforeSend。根据jQuery文档,我可以使用jQuery.ajaxSet

  • 我尝试使用以下代码,得到了回应:状态:405方法不允许。这是我的Http请求:http://localhost:8090/services/test?name=test.代码或http请求有什么问题?

  • 我不熟悉Spring集成。我正在尝试使用http入站网关构建一个简单的应用程序。下面是我得到的运行时异常。 下面是代码文件。 波约 服务 } 服务激活器 } 存储库 请帮助我,我正在试图找到异常发生的原因,但无法解决。提前谢谢。 集成文件。