我有一个 @RestController,它有一种接受多部分请求的方法。
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
void create(@Valid @RequestPart("body") RequestDto request, HttpServletRequest servletRequest);
然后我遍历所有部分并仅存储对文件的 InputStream 的引用,因为主要目标不是在内存中存储任何文件(以任何 byte[] 的形式)。
...
servletRequest.getParts().forEach(part -> {
fileDto.setFileContent(part.getInputStream());
});
...
然后我想调用系统的另一个API,它实际上存储文件。我想使用 spring-cloud-starter-openfeign 中的 @FeignClient。
我在互联网上找到了一些示例,但大多数都使用 java.io.File 或 feign.form.FormData 来创建临时文件(或存储 byte[] 数组)。所以我准备了下面的脚本。
@FeignClient(name = "feignClient", url = "${api.url}", configuration = FeignConfig.class)
public interface ExternalSystemConnector {
@PostMapping(value = "/v1/file", headers = "Content-Type=multipart/form-data", produces = MediaType.MULTIPART_FORM_DATA_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
void createFile(@RequestPart("body") AdditionalInfoDto requestDto,
@RequestPart("file") MultipartFile file);
}
然后我要调用外部系统:
...
externalSystemConnector.createFile(additionalInfoDto, convertToMultiPartFile(fileDto.getInputStream()));
...
但我不知道如何在 convertToMultiPartFile 方法中将 InputStream 转换为 MultipartFile。 MultipartFile 接口还具有 getSize / getBytes 方法,我不知道大小,因为我只保留对 InputStream 的引用。
有谁知道,我怎样才能实现这一目标?或者有什么更好的解决方案吗?主要条件是使用 FeignClient 并且不将文件内容存储在内存中,只是将其流式传输到外部系统。
可以使用java spring的MockMultipartFile类。
public static MultipartFile convert(InputStream inputStream, String filename, String contentType) throws IOException {
return new MockMultipartFile(filename, inputStream);
}
public static void main(String[] args) {
try {
InputStream inputStream = /* Your InputStream */;
String filename = "example.txt";
String contentType = "text/plain";
MultipartFile multipartFile = convert(inputStream, filename, contentType);
} catch (IOException e) {
e.printStackTrace();
}
}