【问题标题】:Http Gateways and Json Transformers: stripped headersHttp 网关和 Json 转换器:剥离的标头
【发布时间】:2014-10-16 23:35:33
【问题描述】:

将 Spring Integration 4.0.3.RELEASE 与 Jackson2 结合使用,我正在尝试将 Json Transformers 与 http 网关结合使用。

我的路径看起来类似于 Spring Integration 文档中引用的 amqp 适配器,但使用的是 http gateways(1):

...->object-to-json-transformer->http-outbound-gateway---->

---->http-inbound-gateway->json-to-object-transformer->

客户:

<int:chain id="messageTransformerChain" input-channel="toServer" output-channel="messagesToServer">
    ...
    <int:object-to-json-transformer />
</int:chain>

<int-http:outbound-gateway id="httpOutToSever"
    request-channel="messagesToServer"
    reply-channel="replyFromServer"
    url="${server.endpoint}"
    http-method="POST"
    extract-request-payload="true"
    expected-response-type="java.lang.String" />

服务器:

<int-http:inbound-gateway id="httpInboundFromClientGateway"
    supported-methods="GET, POST"
    request-channel="fromClientChannel" />

<int:chain input-channel="fromClientChannel">
    <int:json-to-object-transformer />
    ...
</int:chain>

我得到的例外是(我认为相关的是粗体):

2014-08-22T23:58:21.640-0400 警告 [http-bio-8080-exec-2] o.s.i.h.i.HttpRequestHandlingMessagingGateway 故障发生在 网关发送和接收 org.springframework.integration.transformer.MessageTransformationException: 未能在 org.springframework.integration.transformer.AbstractTransformer.transform(AbstractTransformer.java:44) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:68) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:170) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.handler.MessageHandlerChain.handleMessageInternal(MessageHandlerChain.java:131) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:255) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:109) ~[spring-messaging-4.0.6.RELEASE.jar:4.0.6.RELEASE] 在 org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:144) ~[spring-messaging-4.0.6.RELEASE.jar:4.0.6.RELEASE] 在 org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:44) ~[spring-messaging-4.0.6.RELEASE.jar:4.0.6.RELEASE] 在 org.springframework.messaging.core.AbstractMessagingTemplate.sendAndReceive(AbstractMessagingTemplate.java:75) ~[spring-messaging-4.0.6.RELEASE.jar:4.0.6.RELEASE] 在 org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:250) [spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:224) [spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.actualDoHandleRequest(HttpRequestHandlingEndpointSupport.java:473) [spring-integration-http-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.doHandleRequest(HttpRequestHandlingEndpointSupport.java:370) [spring-integration-http-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway.handleRequest(HttpRequestHandlingMessagingGateway.java:101) [spring-integration-http-4.0.3.RELEASE.jar:na] 在 org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51) [spring-webmvc-4.0.6.RELEASE.jar:4.0.6.RELEASE] 在 org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938) [spring-webmvc-4.0.6.RELEASE.jar:4.0.6.RELEASE] 原因: java.lang.IllegalArgumentException:无法解析“json__TypeId__” 在“javaTypes”中。在 org.springframework.integration.support.json.AbstractJacksonJsonObjectMapper.createJavaType(AbstractJacksonJsonObjectMapper.java:67) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.support.json.Jackson2JsonObjectMapper.extractJavaType(Jackson2JsonObjectMapper.java:119) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.support.json.Jackson2JsonObjectMapper.extractJavaType(Jackson2JsonObjectMapper.java:44) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.support.json.AbstractJacksonJsonObjectMapper.fromJson(AbstractJacksonJsonObjectMapper.java:60) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.json.JsonToObjectTransformer.doTransform(JsonToObjectTransformer.java:81) ~[spring-integration-core-4.0.3.RELEASE.jar:na] 在 org.springframework.integration.transformer.AbstractTransformer.transform(AbstractTransformer.java:33) ~[spring-integration-core-4.0.3.RELEASE.jar:na] ... 102个常用框架 省略

调试时,我在客户端看到 json__TypeId__ 标头已从传出消息中删除。当我将JsonHeaders.HEADERS 添加到DefaultHttpHeaderMapper 并使用此映射器注入网关时,我看到当映射器工作完成时,Json 标头存在,但是当我最终回到RestTemplate.doWithRequest requestHeaders 没有不再包含 Json 的。当然,我得到相同的异常服务器端。

也许我的配置不正确,但是由于该标头被剥离,我不确定服务器端将如何进行json-to-object 转换。

我不希望在特定映射器上明确指出通道的类型,因为它们可能会有所不同。有没有办法配置我需要支持此路径的组件?

-- 参考资料--

(1) http://docs.spring.io/spring-integration/reference/html/messaging-transformation-chapter.html#transformer 滚动到 Json Transformers 小节

【问题讨论】:

    标签: java json spring-integration


    【解决方案1】:

    使用出站 http 适配器,用户标头(在他的情况下为 json 类型信息)通过 HTTP 传送为 X-&lt;header&gt;...

    <int-http:outbound-gateway request-channel="requestChannel" 
                               url="http://localhost:18080/http/receiveGateway"
                               http-method="POST"
                               mapped-request-headers="foo"
                               expected-response-type="java.lang.String"/>
    
    POST /http/receiveGateway HTTP/1.1
    Accept: text/plain, */*
    X-foo: bar
    

    在服务器端,X- 未被删除,因此您必须将其与 x 进行映射...

    <int-http:inbound-gateway request-channel="receiveChannel"
                          path="/receiveGateway"
                          mapped-request-headers="x-foo"
                          supported-methods="POST"/>
    

    然后你需要在你的&lt;chain/&gt; 中的&lt;header-enricher/&gt; 在转换器之前设置标题(减去'x-')...

    <int:header-enricher>
        <int:header name="json__TypeId__" expression="headers['x-json__TypeId__']" />
        ...
    </int:header-enricher>
    

    (注意小写x)。

    编辑:

    或者,在发送端,您可以将映射器配置为不为自定义标头添加前缀...

    <bean id="mapper" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper">
        <property name="outboundHeaderNames" value="foo,bar" />
        <property name="userDefinedHeaderPrefix" value="" />
    </bean>
    

    【讨论】:

    • 我一直在尝试第二种方法:将JsonHeader.HEADERS 添加到DefaultHttpHeaderMapper 并设置userDefinedHeaderPrefix =""。 json__TypeId__ 标头仍未被映射出来。经过更多调试后,我发现这是因为此标头的值的类型是java.lang.Class,而setHttpHeader 方法不知道如何转换它,因为默认情况下没有配置ConversionService。那么创建一个转换器来将java.lang.Class值转换为String作为标题是否正确?
    • 在将json__TypeId__ 标头设置为字符串类型值的网关之前,在转换器之后添加header-enricher 可能会更简洁。
    • 一个不同的注释,objectToJsonTransformerjsonToObjectTransformer 一起使用似乎很常见。后者知道如何从java.lang.Classjava.lang.String 中找出json__TypeId__ 标头的值,但前者仅提供java.lang.Class 类型。因此,那里似乎存在不对称性。
    • 好点;请打开一个“改进”[JIRA 问题](jira.spring.io/browse/INT) - 谢谢。
    • @Gary Russell 我遇到了同样的问题。而且我认为 org.springframework.integration.mapping.support.JsonHeaders 中没有标头值。所以我无法转换消息。我用弹簧休息模板成功了。
    猜你喜欢
    • 2010-09-26
    • 2020-12-13
    • 2012-11-07
    • 2023-04-04
    • 1970-01-01
    • 2023-03-25
    • 2014-12-20
    • 1970-01-01
    • 2014-03-16
    相关资源
    最近更新 更多