Johnny Alpha
Johnny Alpha

Reputation: 970

How do I send Microsoft Office Mime Types as Content-Type header with with Spring Boot RestTemplate

I'm building a microservice with Java 8 and SpringBoot, it is to have the folowing flow -

  1. A file will come in, with a GUID as a name and no file extension.
  2. Another xml file will come in containing the file type eg/ xslx
  3. The file type is scraped from the xml
  4. The *file is then sent out on an Http POST with the body as the file payload and a header 'Content-Type' containing the mime-type.

*All MS Office document types are to be supported - https://www.askingbox.com/info/mime-types-of-microsoft-office-file-formats 22 different mime-types are listed there.

I've added a custom MessageConverter to my RestTemplate -

MediaType mt = new MediaType("application", "vnd.openxmlformats-officedocument.spreadsheetml.sheet");
List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
ByteArrayHttpMessageConverter converter = new ByteArrayHttpMessageConverter();
converter.setSupportedMediaTypes(Collections.singletonList(mt));
messageConverters.add(converter);
restTemplate.setMessageConverters(messageConverters);

The problem is Spring AFAIK does not support any of those types, so MediaType.ALL will not cover them. So as soon as I add something like

application/vnd.openxmlformats-officedocument.wordprocessingml.template 

as a Content-Type Header, Spring complains:

No HttpMessageConverter for sun.nio.ch.ChannelInputStream and content type "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

Does anybody have an idea on how I can get Spring to behave and accept the MS mime types : https://www.askingbox.com/info/mime-types-of-microsoft-office-file-formats

Thanks

Upvotes: 0

Views: 1597

Answers (1)

Andreas
Andreas

Reputation: 159215

An HttpMessageConverter converts between byte data and some Java object. As such, it needs to understand both the byte data and the Java object type. The format of the byte data is given as a mime type.

An HttpMessageConverter can e.g. indicate that it supports application/xml and the Document DOM type, and would use a DOM parser when converting in one direction, and an XSLT copy transformation when converting in the other direction.

Another HttpMessageConverter could then indicate that it supports application/xml and a POJO type that's been annotated with @XmlRootElement, and would use JAXB to convert, in both directions.

As you can see, both the mime type and the Java type is important to the HttpMessageConverter.

The error message in the question identifies both the mime type and the Java type:

  • Mime type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

  • Java type: sun.nio.ch.ChannelInputStream

The problem is that although your custom message converter has been configured to say it supports the mime type in question, you used the ByteArrayHttpMessageConverter, and it only supports byte[] as the Java type (see name of message converter class).

Since the Java type is ChannelInputStream, that custom message converter is not applicable, and since there is no other message converter that supports the mime/java type combination, you get that error.

I see two fairly easy solutions:

  1. Load the data from the ChannelInputStream into a byte[], then send that instead of the ChannelInputStream object.

  2. Change the custom message converter to be a ResourceHttpMessageConverter, then wrap the ChannelInputStream object in an InputStreamResource when sending. This will stream the data, using less memory. (Recommended)

Upvotes: 1

Related Questions