0
votes

I have an http:inbound-gateway, receive a json message, do some enrichment and send it to an endpoint using an http:outbound-gateway to call a rest service also with json payload.

Inbound-gw receives the content-type header, it is set on the message header but when the payload is sent to the rest service using the outbound-gw the following error happens: 415 Unsupported Media Type

I checked the log and the following warning shows up:

WARN DefaultHttpHeaderMapper:951 - Header 'content-type' with value 'application/json' will not be set since it is not a String and no Converter is available. Consider registering a Converter with ConversionService (e.g., )

It's strange because the content-type header is set with value application/json and I use the mapped-request-headers="HTTP_REQUEST_HEADERS". I'm using SI 4.3.1.RELEASE, any idea?

Here's the http:inbound-gw

<int-http:inbound-gateway id="restHttpInboundGateway"
        request-channel="restHttpInboundChannel" path="/services"
        supported-methods="GET,POST,PUT,DELETE,PATCH,HEAD"
        reply-channel="restHttpOutboundChannel" 
        mapped-request-headers="http_requestMethod,Content-Length,Accept,Connection, Content-Type">
        <int-http:request-mapping consumes="application/json,application/xml"
            produces="application/json,application/xml" />
    </int-http:inbound-gateway>

and here's the outbound-gw

<int-http:outbound-gateway id="restHttpOutboundGateway"
        request-channel="restHttpOutboundGatewayChannel" reply-channel="restHttpOutboundChannel"
        url-expression="https://localhost:8443/service/rest/contacts/1" mapped-request-headers="HTTP_REQUEST_HEADERS"
        http-method-expression="PUT" expected-response-type="java.lang.String"
        charset="UTF-8"/>

Here's the message logged before the outbound-gw:

2016-10-08 10:07:04,634 INFO serviceMessages:194 - GenericMessage [payload=byte[76], headers={content-length=76, replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@44237f19, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@44237f19, content-type=application/json, connection=keep-alive, id=79012bea-263b-0f48-6e96-5fc832c08da6, accept=[text/plain, /], timestamp=1475932024630}]

2

2 Answers

2
votes

This looks like a bug; the header mapper is supposed to always map Content-Type to/from contentType in Spring Integration messages. The outbound adapter is expecting contentType.

However, the code that does that on the inbound side is looking for Content-Type (case-sensitive) and is getting content-type from Spring MVC. Perhaps something has changed.

It looks like we need to make this mapping test case-insensitive.

In the meantime, you can add a header enricher to copy the header...

<header-enricher ...>
    <header name="contentType" expression="headers['content-type']" />
</header-enricher>

and a header-filter to remove the content-type header (to eliminate the warning log).

0
votes

There is another bug in the DefaultHttpHeaderMapper, when it isn't supplied with the ConversionService, therefore MimeType for your content-type header can't be converted to String.

You can create DefaultHttpHeaderMapper.outboundMapper() bean instead of mapped-request-headers for the <int-http:outbound-gateway>. Or, again: re-map content-type to itself:

<header name="content-type" expression="headers['content-type'].toString()" override="true"/>