2017-10-19 17 views
0

Je suis assez novice avec les API REST et Spring Boot en particulier. Je suis en train de coder un microservice à qui l'on demande des fichiers S3 et je dois les renvoyer d'une manière ou d'une autre. Les fichiers seront trop gros (2GB +) pour rester dans la mémoire du microservice et ensuite le renvoyer à l'appelant, donc je pensais pouvoir simplement retourner un S3Object sérialisé, et mes clients pourraient streamer le contenu du fichier, avec des morceaux, via des appels répétés S3ObjectInputStream.read (octets []). J'ai du mal à rendre cela possible, et en raison de mes connaissances limitées, je ne pense même pas si c'est possible ou si je pense à Wright.Est-il possible de renvoyer un objet S3Object à partir du contrôleur de démarrage Spring?

J'ai essayé de renvoyer un ResponseEntity. Avec Postman tout est cool, et S3Object est sérialisé correctement avec la bibliothèque jackson, mais la désertification du côté client se bloque car la méthode S3Object.setObjectContent est surchargée et plusieurs setters entrent en conflit.

Renvoyer un ResponseEntity avec SerializationUtils.serialize (S3Object) en tant que corps échoue également. Même S3Object implémentant l'interface Serializable, à chaque fois, l'octet [] résultant est de longueur 1000, et quand je désérialise, je ne peux pas obtenir le contenu de l'objet car S3Object.getObjectContent() retourne toujours null.

Que puis-je faire?

+1

Vous ne pouvez pas créer une URL de téléchargement signée et y rediriger? Laisser l'utilisateur le télécharger directement depuis S3 plutôt que via votre serveur? – Ivar

Répondre

0

Pas besoin de ça, je ne pense pas. Voici un exemple de la façon de retourner un fichier demandé l'aide d'un api RESTful:

@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); 
    } 
} 

Ajouter un autre MediaType au « produit » attribut que vous attendez à télécharger à partir de ce point final, ou ajouter un autre critère d'évaluation similaire pour chaque mediatype.