是否可以从Spring Boot Controller中返回一个S3Object?
问题描述:
我很喜欢REST API和Spring Boot。我正在编写一个需要S3文件的微服务,并且必须以某种方式返回它们。文件将会过大(2GB +)以保留在微服务内存中,然后将其发回给调用者,所以我认为我可以简单地返回一个序列化的S3Object,并且我的客户端可以通过重复调用将文件内容与块一起流式传输S3ObjectInputStream.read(字节[])。是否可以从Spring Boot Controller中返回一个S3Object?
我很难让这成为可能,而且由于我的知识水平有限,如果这可能或者我想赖特,我甚至都不会做这件事。
我试过返回ResponseEntity。使用Postman一切都很酷,并且S3Object与jackson库正确序列化,但客户端的非集成化崩溃,因为方法S3Object.setObjectContent被重载并且多个setter冲突。
返回一个ResponseEntity与SerializationUtils.serialize(S3Object)身体也失败了。即使S3Object实现Serializable接口,每次产生的byte []长度都是1000,当我反序列化时,我无法获取对象内容,因为S3Object.getObjectContent()总是返回null。
我该怎么办?
答
没有必要,我不这么认为。这里有一个如何使用一个RESTful API返回所请求的文件的一个示例:
@RequestMapping(
value = "/downloads/{fileName}",
method = {RequestMethod.GET, RequestMethod.OPTIONS},
produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE})
@ResponseStatus(value = HttpStatus.OK)
public void downloadPolicyDocument(
@PathVariable("fileName") String fileName,
HttpServletResponse response) throws IOException {
response.setCharacterEncoding("UTF-8");
response.addHeader("Access-Control-Allow-Headers", "Range");
response.addHeader("Access-Control-Expose-Headers", "Accept-Ranges, Content-Encoding, Content-Length, Content-Range");
response.setHeader("Content-Disposition", "attachment; filename=\"" + id + "\"");
try (InputStream inputStream = yourMethodThatGetsTheFileAsBufferedInputStream(fileName)) {
ReadableByteChannel inputChannel = Channels.newChannel(inputStream);
WritableByteChannel outputChannel = Channels.newChannel(response.getOutputStream());
response.setContentLength(fastChannelCopy(inputChannel, outputChannel));
}
catch (IOException e) {
throw new YourCustom404Exception(e.getMessage(), e);
}
}
添加其他的MediaType给您期望从这个端点下载,或添加其他类似的端点为每个介质类型的“生产”属性。
难道你不能创建一个签名的下载url并重定向到它吗?让用户直接从S3下载而不是通过服务器? – Ivar