2017-08-28 10 views
1

にあるサービスからAWSでのファイルの移動は、私が2つのサービスAとBがあり、ユーザーがファイルのダウンロードに要求することができます。そのために、サービスAはファイルを要求するBに電話をかけ、それを取得し、ユーザーにダウンロード形式で応答を送信します。春ブーツ - 他

私はこれをやろうとしている方法は、サービスBは、コントローラの右の呼び出しを取得し、です。次に、AWSからFileオブジェクトを取得し、FileSystemResourceを作成してResponseEntity<FileSystemResource>に戻します。

私の問題は、Aは、応答を受信したときに、その本体がヌルであるということです。ダウンロードはまだ行われますが、空のファイル(ゼロバイト)が表示されています。どのようなアイデアを私は間違って何ですか?これは可能ですか?

サービスのマイコントローラー

@GetMapping(value = "/get") 
public ResponseEntity<FileSystemResource> downloadDocument(
     HttpServletRequest httpServletRequest, 
     HttpServletResponse httpServletResponse 
) { 
    httpServletResponse.setHeader(
      "Content-Disposition", 
      "attachment; filename=" + filename); 

    httpServletResponse.setHeader(
      "Content-Type", 
      "application/octet-stream" 
    ); 

    return ResponseEntity.ok(
      documentsService.getDocumentToDownload(fileName)); 
} 

サービスB上の私のコントローラは

@GetMapping(value = "/get") 
public ResponseEntity<FileSystemResource> downloadDocument(
     @RequestParam(value = "fileName") String fileName, 
     HttpServletResponse httpServletResponse 
) { 
    File doc = documentsService.getFileForDocumentInS3(
      fileName); 

    return ResponseEntity.ok(
      new FileSystemResource(doc.getAbsolutePath()) 
    ); 
} 

これは、AWSと対話する私のサービスは、(サービスBに)何をするかです。私のaws3Client変数は、転送マネージャを含むラッパーです。 AWSとの接続性は良好です。

public File getFileForDocumentInS3(
     String bucketName, 
     String fileKey 
) { 
    try { 
     File toReturn = File.createTempFile(fileKey, ".tmp"); 
     toReturn.deleteOnExit(); 

     GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, fileKey); 

     awsS3Client.getTransferManager().download(getObjectRequest, toReturn); 

     return toReturn; 
    } catch (Exception ex) { 
     //catching exception here 
    } 
} 
+0

あなたは(serviceB.downloadDocumentでファイルサイズを見ています)これらのメソッドが何かを返す直前にgetFileForDocumentInS3()メソッドで呼び出すことができます。 –

+2

だけの提案:その代わりに、複数のサービス間でのファイルの受け渡し、[署名S3のURL](http://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURLJavaSDK.html)を使用し、クライアントにそのバックパスファイルを直接ダウンロードすることができます。ファイルが一度直接ダウンロードされるため、パフォーマンスが向上し、帯域幅が小さくなります。 –

+0

@AmitKBistはい彼らは、デバッガで見ることができるFileを返します。私はそれが私のコンピュータ上に作成された一時ファイルを指しているのを見ます。ファイルを開いてコンソールにそのコンテンツを表示すると、データが表示されます。 –

答えて

1

あなたは、あなたがバージョンバケット内の特定のバージョンのために署名したURLを生成できなかったため、サービス間でファイルを送信するために選択したコメントで述べました。 SDKのバージョン1.11.123以降

(現在の最新のが1.11.186である)あなたはこのようなGeneratedPresignedUrlRequest.withVersionIdで署名URLのバージョンIDを設定することができます。

final URL url = s3.generatePresignedUrl(
     new GeneratePresignedUrlRequest("my-bucket", "my-key", HttpMethod.GET) 
      .withVersionId("version-id") 
); 
+1

うん、あなたは正しいです。私は古いバージョンのAWSを使用していましたが、オンラインでAPIをチェックしませんでした...新しいバージョンに更新し、それをソートしました。 あなたは、私が有効な回答としてマークされます解答を掲載一つだけですので;) –

+0

私はあなたがコメントでそれを考え出した答えを掲示した後、私は見ました。そのような場合は、あなた自身の質問に答えることができ、将来その人を助けるためにその答えを受け入れることができます – Raniz