2017-10-19 60 views
0

我很喜歡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

回答

0

沒有必要,我不這麼認爲。這裏有一個如何使用一個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給您期望從這個端點下載,或添加其他類似的端點爲每個介質類型的「生產」屬性。

相關問題