如何使用 Spring Boot RestTemplate 将 Microsoft Office Mime 类型作为 Content-Type 标头发送

Posted

技术标签:

【中文标题】如何使用 Spring Boot RestTemplate 将 Microsoft Office Mime 类型作为 Content-Type 标头发送【英文标题】:How do I send Microsoft Office Mime Types as Content-Type header with with Spring Boot RestTemplate 【发布时间】:2021-03-25 02:54:48 【问题描述】:

我正在使用 Java 8 和 SpringBoot 构建一个微服务, 就是要有以下的流程-

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

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

我已将自定义 MessageConverter 添加到我的 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);

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

application/vnd.openxmlformats-officedocument.wordprocessingml.template 

作为 Content-Type Header, 春天抱怨:

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

谢谢

【问题讨论】:

【参考方案1】:

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

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

然后另一个HttpMessageConverter 可以表明它支持application/xml 和一个用@XmlRootElement 注释的POJO 类型,并将使用JAXB 进行双向转换。

如您所见,mime 类型和 Java 类型对于HttpMessageConverter 都很重要。

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

Mime 类型:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

Java 类型:sun.nio.ch.ChannelInputStream

问题在于,虽然您的自定义消息转换器已配置为支持相关的 mime 类型,但您使用了 ByteArrayHttpMessageConverter,并且它仅支持 byte[] 作为 Java 类型 (请参阅消息转换器类).

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

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

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

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

【讨论】:

以上是关于如何使用 Spring Boot RestTemplate 将 Microsoft Office Mime 类型作为 Content-Type 标头发送的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 graphql-spring-boot 向 GraphQL Java 添加检测?

如何在 spring-boot 中禁用 spring-data-mongodb 自动配置

spring-boot如何使用两个DataSource

如何从另一个新的 Spring Boot 项目调用一个 Spring Boot 项目中存在的 Spring Boot api

如何在没有spring-boot的情况下使用eureka+feign?

如何在 Spring Boot 中使用 @Transactional 注解