2017-08-28 4 views
1

J'ai 2 services A et B, et les utilisateurs peuvent demander à A le téléchargement d'un fichier. Pour cela, le service A appelle B pour demander le fichier, l'obtient et envoie une réponse aux utilisateurs sous la forme d'un téléchargement. La façon dont j'essaye de faire ceci est, service B obtient le bon appel dans le contrôleur. Ensuite, il obtient l'objet File à partir d'AWS et crée un FileSystemResource à partir de celui-ci, renvoyant un ResponseEntity<FileSystemResource>.Spring Boot - Déplacement d'un fichier dans AWS d'un service à un autre

Mon problème est que lorsque A reçoit la réponse, son corps est nul. Le téléchargement arrive toujours mais je reçois un fichier vide (zéro octet). Une idée de ce que je fais mal? Est-ce possible?

Mon contrôleur sur le service 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)); 
} 

Mon contrôleur sur le service 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()) 
    ); 
} 

C'est ce que mon service en interaction avec AWS fait (sur le service B). Notez que ma variable aws3Client est ici un wrapper qui contient le gestionnaire de transfert. La connectivité avec AWS est bonne.

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

voyez la taille du fichier à serviceB.downloadDocument() ou dans les méthodes getFileForDocumentInS3() juste avant que ces méthodes retournent quoi que ce soit. –

+2

Juste une suggestion: Au lieu de passer le fichier entre plusieurs services, utilisez [URL S3 signées] (http://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURLJavaSDK.html) et renvoyez-le au client où ils peuvent télécharger le fichier directement. Meilleure performance et moins de bande passante puisque le fichier est téléchargé une fois directement. –

+0

@AmitKBist oui ils retournent un fichier qui peut être vu avec le débogueur et je le vois pointer vers le fichier temporaire créé sur mon ordinateur. Si j'ouvre le fichier pour voir son contenu dans une console, je vois des données. –

Répondre

1

Vous avez mentionné dans les commentaires que vous avez choisi d'envoyer les fichiers entre les services parce que vous ne pouvez générer des URL signés pour des versions spécifiques dans un seau de versionné.

Depuis la version SDK 1.11.123 (courant dernier est 1.11.186), vous pouvez définir l'ID de version d'une URL signé avec GeneratedPresignedUrlRequest.withVersionId comme ceci:

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

Oui, vous avez raison. J'utilisais une ancienne version d'AWS et je n'ai pas vérifié l'API en ligne ... J'ai mis à jour vers une version plus récente et je l'ai triée. Puisque vous êtes le seul qui a posté une réponse je la marquerai comme la réponse valide;) –

+0

J'ai vu après que j'ai posté la réponse que vous l'avez compris dans les commentaires. Dans ces cas, vous pouvez répondre à votre propre question et accepter cette réponse pour aider les autres à l'avenir – Raniz