Http Gateways and Json Transformers: stripped head

2019-06-03 00:16发布

Using Spring Integration 4.0.3.RELEASE with Jackson2, I am trying to use Json Transformers in conjunction with http gateways.

My pathway looks akin to that of the amqp adapter referenced in the Spring Integration documentation but with http gateways(1):

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

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

Client:

<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" />

Server:

<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>

The exception I am getting is (what I think is relevant is in bold):

2014-08-22T23:58:21.640-0400 WARN [http-bio-8080-exec-2] o.s.i.h.i.HttpRequestHandlingMessagingGateway failure occurred in gateway sendAndReceive org.springframework.integration.transformer.MessageTransformationException: failed to transform message at org.springframework.integration.transformer.AbstractTransformer.transform(AbstractTransformer.java:44) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:68) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:170) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.handler.MessageHandlerChain.handleMessageInternal(MessageHandlerChain.java:131) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:255) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:109) ~[spring-messaging-4.0.6.RELEASE.jar:4.0.6.RELEASE] at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:144) ~[spring-messaging-4.0.6.RELEASE.jar:4.0.6.RELEASE] at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:44) ~[spring-messaging-4.0.6.RELEASE.jar:4.0.6.RELEASE] at org.springframework.messaging.core.AbstractMessagingTemplate.sendAndReceive(AbstractMessagingTemplate.java:75) ~[spring-messaging-4.0.6.RELEASE.jar:4.0.6.RELEASE] at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:250) [spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:224) [spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.actualDoHandleRequest(HttpRequestHandlingEndpointSupport.java:473) [spring-integration-http-4.0.3.RELEASE.jar:na] at org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.doHandleRequest(HttpRequestHandlingEndpointSupport.java:370) [spring-integration-http-4.0.3.RELEASE.jar:na] at org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway.handleRequest(HttpRequestHandlingMessagingGateway.java:101) [spring-integration-http-4.0.3.RELEASE.jar:na] at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51) [spring-webmvc-4.0.6.RELEASE.jar:4.0.6.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938) [spring-webmvc-4.0.6.RELEASE.jar:4.0.6.RELEASE] Caused by: java.lang.IllegalArgumentException: Could not resolve 'json__TypeId__' in 'javaTypes'. at org.springframework.integration.support.json.AbstractJacksonJsonObjectMapper.createJavaType(AbstractJacksonJsonObjectMapper.java:67) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.support.json.Jackson2JsonObjectMapper.extractJavaType(Jackson2JsonObjectMapper.java:119) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.support.json.Jackson2JsonObjectMapper.extractJavaType(Jackson2JsonObjectMapper.java:44) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.support.json.AbstractJacksonJsonObjectMapper.fromJson(AbstractJacksonJsonObjectMapper.java:60) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.json.JsonToObjectTransformer.doTransform(JsonToObjectTransformer.java:81) ~[spring-integration-core-4.0.3.RELEASE.jar:na] at org.springframework.integration.transformer.AbstractTransformer.transform(AbstractTransformer.java:33) ~[spring-integration-core-4.0.3.RELEASE.jar:na] ... 102 common frames omitted

When I debug, I see on the client side that the json__TypeId__ header has been stripped from the outgoing message. When I add JsonHeaders.HEADERS to a DefaultHttpHeaderMapper and inject the Gateways with this mapper, I see that when the mapper work is done, the Json headers ARE present, but when I end up back in RestTemplate.doWithRequest the requestHeaders no longer contain the Json ones. And of course, I get the same exception server side.

Perhaps my configurations are incorrect, but with that header being stripped I'm not sure how the server side would be able to do json-to-object transformation.

I would prefer not to explicitly indicate type on specific Mappers for channels since they can vary. Is there a way to configure the components I need to support this pathway?

-- References --

(1) http://docs.spring.io/spring-integration/reference/html/messaging-transformation-chapter.html#transformer Scroll to Json Transformers subsection

1条回答
叼着烟拽天下
2楼-- · 2019-06-03 00:40

With the outbound http adapter, user headers (in his case the json type information) are conveyed over HTTP as X-<header>...

<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

On the server side, the X- is not removed so you have to map it with the x...

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

You will then need a <header-enricher/> in your <chain/> before the transformer to set the headers (minus the 'x-')...

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

(Note lower case x).

EDIT:

Or, on the sending side, you can configure the mapper to NOT prefix the custom header(s)...

<bean id="mapper" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper">
    <property name="outboundHeaderNames" value="foo,bar" />
    <property name="userDefinedHeaderPrefix" value="" />
</bean>
查看更多
登录 后发表回答