是否可以从Spring Boot Controller中返回一个S3Object?

是否可以从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。

我该怎么办?

+1

难道你不能创建一个签名的下载url并重定向到它吗?让用户直接从S3下载而不是通过服务器? – Ivar

没有必要,我不这么认为。这里有一个如何使用一个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给您期望从这个端点下载,或添加其他类似的端点为每个介质类型的“生产”属性。