Reputation: 702
Creating an HTTP proxy in Spring Integration 4.2.1.RELEASE. Environment is using the latest 2.0.0.RELEASE platform BOM, including a spring-webmvc layer - running on Tomcat7.
Calls are "application/json", passed through the web layer to a different REST server endpoint (the setupUrl method rewrites the URL). The code successfully calls the external server, gets good response, then mangles the response before it returns to the caller.
@Bean
public IntegrationFlow httpProxyFlow() {
return IntegrationFlows
.from((MessagingGateways g) ->
g.httpGateway("/my-service/**")
.messageConverters(new MappingJackson2HttpMessageConverter())
.payloadFunction(httpEntity ->
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest()
.getQueryString())
.requestPayloadType(String.class))
.handleWithAdapter(a ->
a.httpGateway(this::setupUrl)
.httpMethodFunction(this::getMethodFunction)
.errorHandler(new PassThroughErrorHandler())
.encodeUri(false)
.expectedResponseType(String.class)
).get();
}
The call directly to the REST endpoint returns
{"affiliate":"test","producer":"TST","products"...
While the call through Spring Integration returns
"{\"affiliate\":\"test\",\"producer\":\"TST\",\"products\":[{\"
Tried a lot of combinations of adding StringHttpMessageConverter to the outbound adapter. Messing with the encodings (UTF-8 rather than ISO-8859-1). Something is messing with the response string, and it seems to be AFTER it leaves Spring Integration as near as I can tell. The last time Integration touches it is HttpRequestHandlingMessagingGateway.handleRequest() line 117. It still looks correct in the response object there.
It's possible the issue is really with spring-mvc, that is the first place I see the mangled string in debugging.
Upvotes: 0
Views: 336
Reputation: 174779
Best guess is some problem with the accept
(inbound) or content-type
(outbound).
I just changed the http sample like so...
<int-http:inbound-gateway request-channel="proxyChannel"
reply-channel="reply"
path="/receiveGateway"
supported-methods="POST"/>
<int:channel id="reply" />
<int-http:outbound-gateway request-channel="proxyChannel"
reply-channel="reply"
expected-response-type="java.lang.String"
url="http://localhost:8080/http/receiveGateway2"/>
<int-http:inbound-gateway request-channel="receiveChannel"
path="/receiveGateway2"
supported-methods="POST"/>
<int:channel id="receiveChannel"/>
<int:chain input-channel="receiveChannel">
<int:header-filter header-names="content-type" />
<int:service-activator expression='{"foo" : "bar"}'/>
</int:chain>
The payload being returned to the first gateway is type String
; it works for me with an inbound accept
of text/plain
or application/json
.
Since the StringHttpMessageConverter
is ahead of the JSON message converter in the list, and the payload is a String
, it is chosen because the type is String
and that converter can handle */*
accept
, so there's no double JSON encoding.
{"foo":"bar"}
is received by my client.
If you can't figure it out with DEBUG logging and/or the debugger, you could try reconfiguring the inbound gateway with just a StringHttpMessageConverter
.
Set a breakpoint at line 151 (current release) in HttpRequestHandlingMessagingGateway
to see which outbound message converter is being selected.
Upvotes: 1