首页 > 解决方案 > 如何使用 Spring Boot RestTemplate 将 Microsoft Office Mime 类型作为 Content-Type 标头发送

问题描述

我正在使用 Java 8 和 SpringBoot 构建一个微服务,它具有以下流程 -

  1. 将进入一个文件,其名称为 GUID,没有文件扩展名。
  2. 另一个 xml 文件将包含文件类型 eg/xslx
  3. 文件类型是从 xml 中抓取的
  4. 然后将 *file 通过 Http POST 发送出去,正文作为文件有效负载,标头“Content-Type”包含 mime-type。

*支持所有 MS Office 文档类型 - https://www.askingbox.com/info/mime-types-of-microsoft-office-file-formats 那里列出了 22 种不同的 mime 类型。

我在我的 RestTemplate 中添加了一个自定义 MessageConverter -

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

问题是 Spring AFAIK 不支持任何这些类型,因此 MediaType.ALL 不会涵盖它们。所以只要我添加类似的东西

application/vnd.openxmlformats-officedocument.wordprocessingml.template 

作为 Content-Type Header,Spring 抱怨:

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

有人知道我如何让 Spring 表现并接受 MS mime 类型:https ://www.askingbox.com/info/mime-types-of-microsoft-office-file-formats

谢谢

标签: javaspringspring-bootrestms-office

解决方案


HttpMessageConverter字节数据和一些 Java 对象之间的转换。因此,它需要了解字节数据Java 对象类型。字节数据的格式以 MIME 类型给出。

例如HttpMessageConverter,可以表明它支持DOM 类型,application/xml并且Document在一个方向转换时使用 DOM 解析器,在另一个方向转换时使用 XSLT 复制转换。

然后另一个HttpMessageConverter可以指示它支持application/xml一个已用 注释的 POJO 类型,@XmlRootElement并将使用 JAXB 在两个方向上进行转换。

如您所见,mime 类型和 Java 类型对于HttpMessageConverter.

问题中的错误消息标识了 mime 类型和 Java 类型:

  • 哑剧类型:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

  • Java类型:sun.nio.ch.ChannelInputStream

问题是,尽管您的自定义消息转换器已配置为支持相关的 mime 类型,但您使用了ByteArrayHttpMessageConverter, 并且它仅支持byte[]Java 类型(请参阅消息转换器类的名称)

由于 Java 类型是ChannelInputStream,因此该自定义消息转换器不适用,并且由于没有其他支持 mime/java 类型组合的消息转换器,您会收到该错误。

我看到两个相当简单的解决方案:

  1. 将数据从 加载ChannelInputStream到 中byte[],然后发送它而不是ChannelInputStream对象。

  2. 将自定义消息转换器更改为 a ,然后在发送时将对象ResourceHttpMessageConverter包装在 an 中。这将流式传输数据,使用更少的内存。(推荐的)ChannelInputStreamInputStreamResource


推荐阅读