2017-10-19 15 views
0

私は特にREST APIとSpring Bootを使っています。私はS3ファイルを要求され、何らかの形でそれらを返さなければならないマイクロサービスをコーディングしています。ファイルは大きすぎて(2GB +)、マイクロサービスのメモリに保存してから呼び出し元に送り返すので、シリアライズされたS3Objectを返すだけで、クライアントはファイルの内容をチャンクでストリームすることができますS3ObjectInputStream.read(bytes [])Spring Boot ControllerからS3Objectを返すことはできますか?

私はこれを可能にするのに苦労しています。私の限られた知識のために、これが可能であれば、私はライトも考えています。

私はResponseEntityを返そうとしました。 Postmanではすべてがクールで、S3Objectはjacksonライブラリで正しくシリアライズされますが、メソッドS3Object.setObjectContentがオーバーロードされ、複数のセッターが競合するため、クライアント側の脱塩がクラッシュします。

BodyとしてSerializationUtils.serialize(S3Object)を使用してResponseEntityを返すことも失敗します。 Serializableインターフェイスを実装しているS3Objectでも、結果として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のための別の同様のエンドポイントを追加する他のMediaTypeを追加します。

関連する問題